home *** CD-ROM | disk | FTP | other *** search
/ Apple Developer Connection Student Program / ADC Tools Sampler CD Disk 3 1999.iso / Metrowerks CodeWarrior / Java Support / Java_Source / Java2 / src / javax / swing / JComponent.java < prev    next >
Encoding:
Java Source  |  1999-05-28  |  124.3 KB  |  3,769 lines  |  [TEXT/CWIE]

  1. /*
  2.  * @(#)JComponent.java    2.95 98/09/18
  3.  *
  4.  * Copyright 1997, 1998 by Sun Microsystems, Inc.,
  5.  * 901 San Antonio Road, Palo Alto, California, 94303, U.S.A.
  6.  * All rights reserved.
  7.  *
  8.  * This software is the confidential and proprietary information
  9.  * of Sun Microsystems, Inc. ("Confidential Information").  You
  10.  * shall not disclose such Confidential Information and shall use
  11.  * it only in accordance with the terms of the license agreement
  12.  * you entered into with Sun.
  13.  */
  14. package javax.swing;
  15.  
  16.  
  17. import java.util.Hashtable;
  18. import java.util.Dictionary;
  19. import java.util.Enumeration;
  20. import java.util.Locale;
  21. import java.util.Vector;
  22.  
  23. import java.awt.*;
  24. import java.awt.event.*;
  25. import java.beans.*;
  26.  
  27. import java.applet.Applet;
  28.  
  29. import java.io.Serializable;
  30. import java.io.ObjectOutputStream;
  31. import java.io.ObjectInputStream;
  32. import java.io.IOException;
  33. import java.io.ObjectInputValidation;
  34. import java.io.InvalidObjectException;
  35.  
  36. import javax.swing.border.*;
  37. import javax.swing.event.*;
  38. import javax.swing.plaf.*;
  39. import javax.accessibility.*;
  40.  
  41.  
  42.  
  43. import java.awt.Graphics2D;
  44.   
  45.  
  46. /**
  47.  * The base class for the Swing components. JComponent provides:
  48.  * <ul>
  49.  * <li>A "pluggable look and feel" (l&f) that can be specified by the
  50.  *     programmer or (optionally) selected by the user at runtime.
  51.  * <li>Components that are designed to be combined and extended in order
  52.  *     to create custom components.
  53.  * <li>Comprehensive keystroke-handling that works with nested components.
  54.  * <li>Action objects, for single-point control of program actions initiated
  55.  *     by multiple components.
  56.  * <li>A border property that implicitly defines the component's insets.
  57.  * <li>The ability to set the preferred, minimim, and maximum size for a
  58.  *     component.
  59.  * <li>ToolTips -- short descriptions that pop up when the cursor lingers
  60.  *     over a component.
  61.  * <li>Autoscrolling -- automatic scrolling in a list, table, or tree that
  62.  *     occurs when the user is dragging the mouse.
  63.  * <li>Simple, easy dialog construction using static methods in the JOptionPane
  64.  *     class that let you display information and query the user.
  65.  * <li>Slow-motion graphics rendering using debugGraphics so you can see
  66.  *     what is being displayed on screen and whether or not it is being
  67.  *     overwritten.
  68.  * <li>Support for Accessibility.
  69.  * <li>Support for international Localization.
  70.  * </ul>
  71.  * For more information on these subjects, see the
  72.  * <a href="package-summary.html#package_description">Swing package description</a>
  73.  * <p>
  74.  * <strong>Warning:</strong>
  75.  * Serialized objects of this class will not be compatible with
  76.  * future Swing releases.  The current serialization support is appropriate
  77.  * for short term storage or RMI between applications running the same
  78.  * version of Swing.  A future release of Swing will provide support for
  79.  * long term persistence.
  80.  *
  81.  * @see KeyStroke
  82.  * @see Action
  83.  * @see #setBorder
  84.  * @see #registerKeyboardAction
  85.  * @see JOptionPane
  86.  * @see #setDebugGraphicsOptions
  87.  * @see #setToolTipText
  88.  * @see #setAutoscrolls
  89.  *
  90.  * @version 2.95 09/18/98
  91.  * @author Hans Muller
  92.  * @author Arnaud Weber
  93.  */
  94. public abstract class JComponent extends Container implements Serializable
  95. {
  96.     /**
  97.      * @see #getUIClassID
  98.      * @see #writeObject
  99.      */
  100.     private static final String uiClassID = "ComponentUI";
  101.  
  102.     /**
  103.      * @see ReadObjectCallback
  104.      * @se #readObject
  105.      */ 
  106.     private static final Hashtable readObjectCallbacks = new Hashtable(1);
  107.  
  108.  
  109.     /* The following fields support set methods for the corresponding
  110.      * java.awt.Component properties.
  111.      */
  112.  
  113.     private Dimension preferredSize;
  114.     private Dimension minimumSize;
  115.     private Dimension maximumSize;
  116.     private Float alignmentX;
  117.     private Float alignmentY;
  118.     private AncestorNotifier ancestorNotifier;
  119.     Rectangle _bounds = new Rectangle();
  120.  
  121.  
  122.     /* Backing store for JComponent properties and listeners
  123.      */
  124.  
  125.     protected transient ComponentUI ui;
  126.     protected EventListenerList listenerList = new EventListenerList();
  127.  
  128.     private Hashtable clientProperties;
  129.     private VetoableChangeSupport vetoableChangeSupport;
  130.     private Autoscroller autoscroller;
  131.     private Border border;
  132.     private int flags;
  133.  
  134.     /* A "scratch pad" rectangle used by the painting code.
  135.      */
  136.     private transient Rectangle tmpRect;
  137.  
  138.     /**
  139.      * Constant used for registerKeyboardAction() which
  140.      * means that the command should be invoked when
  141.      * the component has the focus.
  142.      */
  143.     public static final int WHEN_FOCUSED = 0;
  144.  
  145.     /**
  146.      * Constant used for registerKeyboardAction() which
  147.      * means that the comand should be invoked when the receiving
  148.      * component is an ancestor of the focused component or is
  149.      * itself the focused component.
  150.      */
  151.     public static final int WHEN_ANCESTOR_OF_FOCUSED_COMPONENT = 1;
  152.  
  153.     /**
  154.      * Constant used for registerKeyboardAction() which
  155.      * means that the command should be invoked when
  156.      * the receiving component is in the window that has the focus
  157.      * or is itself the focused component.
  158.      */
  159.     public static final int WHEN_IN_FOCUSED_WINDOW = 2;
  160.  
  161.     /**
  162.      * Constant used by some of the apis to mean that no condition is defined.
  163.      */
  164.     public static final int UNDEFINED_CONDITION = -1;
  165.  
  166.     /**
  167.      * The key used by JComponent to access keyboard bindings.
  168.      */
  169.     private static final String KEYBOARD_BINDINGS_KEY = "_KeyboardBindings";
  170.  
  171.     /**
  172.      * The comment to display when the cursor is over the component,
  173.      * also known as a "value tip", "flyover help", or "flyover label".
  174.      */
  175.     public static final String TOOL_TIP_TEXT_KEY = "ToolTipText";
  176.  
  177.     private static final String NEXT_FOCUS = "nextFocus";
  178.  
  179.     /** Private flags **/
  180.     private static final int REQUEST_FOCUS_DISABLED = 0;
  181.     private static final int IS_DOUBLE_BUFFERED     = 1;
  182.     private static final int ANCESTOR_USING_BUFFER  = 2;
  183.     private static final int IS_PAINTING_TILE       = 3;
  184.     private static final int HAS_FOCUS              = 4;
  185.     private static final int IS_OPAQUE              = 5;
  186.  
  187.     /**
  188.      * Default JComponent constructor.  This constructor does
  189.      * no initialization beyond calling the Container constructor,
  190.      * e.g. the initial layout manager is null.
  191.      */
  192.     public JComponent() {
  193.         super();
  194.         enableEvents(AWTEvent.FOCUS_EVENT_MASK);
  195.     enableSerialization();
  196.     }
  197.  
  198.  
  199.     /**
  200.      * Resets the UI property to a value from the current look and feel.
  201.      * JComponent subclasses must override this method like this:
  202.      * <pre>
  203.      *   public void updateUI() {
  204.      *      setUI((SliderUI)UIManager.getUI(this);
  205.      *   }
  206.      *  </pre>
  207.      *
  208.      * @see #setUI
  209.      * @see UIManager#getLookAndFeel
  210.      * @see UIManager#getUI
  211.      */
  212.     public void updateUI() {}
  213.  
  214.  
  215.     /**
  216.      * Set the look and feel delegate for this component.
  217.      * JComponent subclasses generally override this method
  218.      * to narrow the argument type, e.g. in JSlider:
  219.      * <pre>
  220.      * public void setUI(SliderUI newUI) {
  221.      *     super.setUI(newUI);
  222.      * }
  223.      *  </pre>
  224.      * <p>
  225.      * Additionaly JComponent subclasses must provide a getUI
  226.      * method that returns the correct type, e.g.
  227.      * <pre>
  228.      * public SliderUI getUI() {
  229.      *     return (SliderUI)ui;
  230.      * }
  231.      * </pre>
  232.      *
  233.      * @see #updateUI
  234.      * @see UIManager#getLookAndFeel
  235.      * @see UIManager#getUI
  236.      * @beaninfo
  237.      *        bound: true
  238.      *    attribute: visualUpdate true
  239.      *  description: The component's look and feel delegate
  240.      */
  241.     protected void setUI(ComponentUI newUI) {
  242.         /* We do not check that the UI instance is different
  243.          * before allowing the switch in order to enable the
  244.          * same UI instance *with different default settings*
  245.          * to be installed.
  246.          */
  247.         if (ui != null) {
  248.             ui.uninstallUI(this);
  249.         }
  250.         ComponentUI oldUI = ui;
  251.         ui = newUI;
  252.         if (ui != null) {
  253.             ui.installUI(this);
  254.         }
  255.         firePropertyChange("UI", oldUI, newUI);
  256.         revalidate();
  257.         repaint();
  258.     }
  259.  
  260.  
  261.     /**
  262.      * Return the UIDefaults key used to look up the name of the
  263.      * swing.plaf.ComponentUI class that defines the look and feel
  264.      * for this component.  Most applications will never need to
  265.      * call this method.  Subclasses of JComponent that support
  266.      * pluggable look and feel should override this method to
  267.      * return a UIDefaults key that maps to the ComponentUI subclass 
  268.      * that defines their look and feel.
  269.      *
  270.      * @return The UIDefaults key for a ComponentUI subclass.
  271.      * @see UIDefaults#getUI
  272.      * @beaninfo
  273.      *      expert: true
  274.      * description: UIClassID
  275.      */
  276.     public String getUIClassID() {
  277.         return uiClassID;
  278.     }
  279.  
  280.  
  281.     /**
  282.      * Returns the graphics object used to paint this component.
  283.      * If DebugGraphics is turned on we create a new DebugGraphics
  284.      * object if neccessary otherwise we just configure the
  285.      * specified graphics objects foreground and font.
  286.      *
  287.      * @return A Graphics object configured for this component
  288.      */
  289.     protected Graphics getComponentGraphics(Graphics g) {
  290.         Graphics componentGraphics = g;
  291.         if (ui != null) {
  292.             if ((DebugGraphics.debugComponentCount() != 0) &&
  293.                     (shouldDebugGraphics() != 0) &&
  294.                     !(g instanceof DebugGraphics)) {
  295.                 if(g instanceof SwingGraphics) {
  296.                     if(!(((SwingGraphics)g).subGraphics() instanceof DebugGraphics)) {
  297.                         componentGraphics = new DebugGraphics(((SwingGraphics)g).subGraphics(),this);
  298.                         componentGraphics = SwingGraphics.createSwingGraphics(componentGraphics);
  299.                     }
  300.                 } else {
  301.                     componentGraphics = new DebugGraphics(g,this);
  302.                 }
  303.             }
  304.         }
  305.         componentGraphics.setColor(getForeground());
  306.         componentGraphics.setFont(getFont());
  307.  
  308.         return componentGraphics;
  309.     }
  310.  
  311.  
  312.     /**
  313.      * If the UI delegate is non-null, call its paint
  314.      * method.  We pass the delegate a copy of the Graphics
  315.      * object to protect the rest of the paint code from
  316.      * irrevocable changes (e.g. Graphics.translate()).
  317.      *
  318.      * @see #paint
  319.      */
  320.     protected void paintComponent(Graphics g) {
  321.         if (ui != null) {
  322.             Graphics scratchGraphics = SwingGraphics.createSwingGraphics(g);
  323.             try {
  324.                 ui.update(scratchGraphics, this);
  325.             }
  326.             finally {
  327.                 scratchGraphics.dispose();
  328.             }
  329.         }
  330.     }
  331.  
  332.     /**
  333.      * Paint this component's children.
  334.      * If shouldUseBuffer is true, no component ancestor has a buffer and
  335.      * the component children can use a buffer if they have one.
  336.      * Otherwise, one ancestor has a buffer currently in use and children
  337.      * should not use a buffer to paint.
  338.      * @see #paint
  339.      * @see java.awt.Container#paint
  340.      */
  341.     protected void paintChildren(Graphics g) {
  342.         boolean isJComponent;
  343.         Graphics sg = SwingGraphics.createSwingGraphics(g);
  344.  
  345.         try {
  346.             synchronized(getTreeLock()) {
  347.                 for (int i = getComponentCount() - 1 ; i >= 0 ; i--) {
  348.                     Component comp = getComponent(i);
  349.                     if (comp != null && isLightweightComponent(comp) && 
  350.                         (comp.isVisible() == true)) {
  351.                         Rectangle cr;
  352.                         isJComponent = (comp instanceof JComponent);
  353.  
  354.                         if(isJComponent) {
  355.                             if(tmpRect == null) {
  356.                                 tmpRect = new Rectangle();
  357.                             }
  358.                             cr = tmpRect;
  359.                             ((JComponent)comp).getBounds(cr);
  360.                         } else {
  361.                             cr = comp.getBounds();
  362.                         }
  363.  
  364.               
  365.             boolean hitClip = 
  366.                 g.hitClip(cr.x, cr.y, cr.width, cr.height);
  367.                 
  368.  
  369.  
  370.  
  371.  
  372.  
  373.  
  374.                         if (hitClip) {
  375.                             Graphics cg = SwingGraphics.createSwingGraphics(
  376.                                 sg, cr.x, cr.y, cr.width, cr.height);
  377.                             boolean shouldSetFlagBack = false;
  378.                             try {
  379.                                 if(isJComponent) {
  380.                                     if(getFlag(ANCESTOR_USING_BUFFER)) {
  381.                                         ((JComponent)comp).setFlag(ANCESTOR_USING_BUFFER,true);
  382.                                         shouldSetFlagBack = true;
  383.                                     }
  384.                                     if(getFlag(IS_PAINTING_TILE)) {
  385.                                         ((JComponent)comp).setFlag(IS_PAINTING_TILE,true);
  386.                                         shouldSetFlagBack = true;
  387.                                     }
  388.                                     ((JComponent)comp).paint(cg);
  389.                                 } else {
  390.                                     comp.paint(cg);
  391.                                 }
  392.                             } finally {
  393.                                 cg.dispose();
  394.                                 if(shouldSetFlagBack) {
  395.                                     ((JComponent)comp).setFlag(ANCESTOR_USING_BUFFER,false);
  396.                                     ((JComponent)comp).setFlag(IS_PAINTING_TILE,false);
  397.                                 }
  398.                             }
  399.                         }
  400.                     }
  401.  
  402.                 }
  403.             }
  404.         } finally {
  405.             sg.dispose();
  406.         }
  407.     }
  408.  
  409.     /**
  410.      * Paint the component's border.
  411.      *
  412.      * @see #paint
  413.      * @see #setBorder
  414.      */
  415.     protected void paintBorder(Graphics g) {
  416.         Border border = getBorder();
  417.         if (border != null) {
  418.             border.paintBorder(this, g, 0, 0, getWidth(), getHeight());
  419.         }
  420.     }
  421.  
  422.  
  423.     /**
  424.      * Calls paint(g).  Doesn't clear the background but see
  425.      * ComponentUI.update() which is called by paintComponent.
  426.      *
  427.      * @see #paint
  428.      * @see #paintComponent
  429.      * @see javax.swing.plaf.ComponentUI
  430.      */
  431.     public void update(Graphics g) {
  432.         paint(g);
  433.     }
  434.  
  435.  
  436.     /**
  437.      * This method is invoked by Swing to draw components.
  438.      * Applications should not invoke paint directly,
  439.      * but should instead use the <code>repaint</code> method to
  440.      * schedule the component for redrawing.
  441.      * <p>
  442.      * This method actually delegates the work of painting to three
  443.      * protected methods: <code>paintComponent</code>, <code>paintBorder</code>,
  444.      * and <code>paintChildren</code>.  They're called in the order
  445.      * listed to ensure that children appear on top of component itself.
  446.      * Generally speaking, the component and its children should not
  447.      * paint in the insets area allocated to the border. Subclasses can
  448.      * just override this method, as always.  A subclass that just
  449.      * wants to specialize the UI (look and feel) delegates paint
  450.      * method should just override <code>paintComponent</code>.
  451.      *
  452.      * @see #paintComponent
  453.      * @see #paintBorder
  454.      * @see #paintChildren
  455.      * @see #getComponentGraphics
  456.      * @see #repaint
  457.      */
  458.     public void paint(Graphics g) {
  459.     boolean shouldClearPaintFlags = false;
  460.  
  461.         if ((getWidth() <= 0) || (getHeight() <= 0)) {
  462.             return;
  463.         }
  464.  
  465.         Graphics componentGraphics = getComponentGraphics(g);
  466.         Graphics co = SwingGraphics.createSwingGraphics(componentGraphics);
  467.         try {
  468.             Image offscr = null;
  469.             RepaintManager repaintManager = RepaintManager.currentManager(this);
  470.       
  471.         Rectangle clipRect = co.getClipBounds();
  472.             int clipX = clipRect.x;
  473.             int clipY = clipRect.y;
  474.             int clipW = clipRect.width;
  475.             int clipH = clipRect.height;
  476.         
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483.  
  484.  
  485.  
  486.  
  487.  
  488.  
  489.  
  490.             if(clipW > getWidth()) {
  491.                 clipW = getWidth();
  492.             }
  493.             if(clipH > getHeight()) {
  494.                 clipH = getHeight();
  495.             }
  496.  
  497.             if(getParent() != null && !(getParent() instanceof JComponent)) {
  498.                 adjustPaintFlags();
  499.                 shouldClearPaintFlags = true;
  500.             }
  501.  
  502.             if(repaintManager.isDoubleBufferingEnabled() &&
  503.                !getFlag(ANCESTOR_USING_BUFFER) && isDoubleBuffered()) {
  504.                 int bw,bh;
  505.                 int x,y,maxx,maxy;
  506.                 offscr = repaintManager.getOffscreenBuffer(this,clipW,clipH);
  507.  
  508.                 Graphics sg = 
  509.                     SwingGraphics.createSwingGraphics(offscr.getGraphics());
  510.                 try {
  511.                     sg.translate(-clipX,-clipY);
  512.  
  513.                     bw = offscr.getWidth(null);
  514.                     bh = offscr.getHeight(null);
  515.  
  516.                     if (bw > clipW) {
  517.                         bw = clipW;
  518.                     }
  519.                     if (bh > clipH) {
  520.                         bh = clipH;
  521.                     }
  522.  
  523.                     setFlag(ANCESTOR_USING_BUFFER,true);
  524.                     setFlag(IS_PAINTING_TILE,true);
  525.                     for(x = 0, maxx = clipW; x < maxx ;  x += bw ) {
  526.                         for(y=0, maxy = clipH; y < maxy ; y += bh) {
  527.                             if((y+bh) >= maxy && (x+bw) >= maxx)
  528.                                 setFlag(IS_PAINTING_TILE,false);
  529.                             sg.translate(-x,-y);
  530.                             sg.setClip(clipX+x,clipY + y,bw,bh);
  531.                             if(!rectangleIsObscured(clipX,clipY,bw,bh)) {
  532.                                 paintComponent(sg);
  533.                                 paintBorder(sg);
  534.                             }
  535.                             paintChildren(sg);
  536.                             co.drawImage(offscr,clipX + x,clipY + y,this);
  537.                             sg.translate(x,y);
  538.                         }
  539.                     }
  540.                 } finally {
  541.                     setFlag(ANCESTOR_USING_BUFFER,false);
  542.                     setFlag(IS_PAINTING_TILE,false);
  543.                     sg.dispose();
  544.                 }
  545.             } else {
  546.                 if (!rectangleIsObscured(clipX,clipY,clipW,clipH)) {
  547.                     paintComponent(co);
  548.                     paintBorder(co);
  549.                 }
  550.                 paintChildren(co);
  551.             }
  552.         } finally {
  553.             co.dispose();
  554.             if(shouldClearPaintFlags) {
  555.                 setFlag(ANCESTOR_USING_BUFFER,false);
  556.                 setFlag(IS_PAINTING_TILE,false);
  557.             }
  558.         }
  559.     }
  560.     
  561.     private void adjustPaintFlags() {
  562.     JComponent jparent = null;
  563.     Container parent;
  564.     for(parent = getParent() ; parent != null ; parent =
  565.         parent.getParent()) {
  566.         if(parent instanceof JComponent) {
  567.         jparent = (JComponent) parent;
  568.         if(jparent.getFlag(ANCESTOR_USING_BUFFER))
  569.           setFlag(ANCESTOR_USING_BUFFER, true);
  570.         if(jparent.getFlag(IS_PAINTING_TILE))
  571.           setFlag(IS_PAINTING_TILE, true);
  572.         break;
  573.         }
  574.     }
  575.     }
  576.     
  577.  
  578.     /**
  579.      *  Returns true if the receiving component is currently painting a tile.
  580.      *  If this method returns true, paint will be called again for another
  581.      *  tile. This method returns false if you are not painting a tile or
  582.      *  if the last tile is painted.
  583.      *  Use this method to keep some state you might need between tiles.
  584.      */
  585.     public boolean isPaintingTile() {
  586.         return getFlag(IS_PAINTING_TILE);
  587.     }
  588.  
  589.  
  590.     /**
  591.      * Override this method and return true if your component is the root of
  592.      * of a component tree with its own focus cycle.
  593.      */
  594.     public boolean isFocusCycleRoot() {
  595.         return false;
  596.     }
  597.  
  598.     /**
  599.      * Override this method and return true if your JComponent manages focus.
  600.      * If your component manages focus, the focus manager will handle your
  601.      * component's children. All key event will be sent to your key listener
  602.      * including TAB and SHIFT+TAB. CONTROL + TAB and CONTROL + SHIFT + TAB
  603.      * will move the focus to the next / previous component.
  604.      */
  605.     public boolean isManagingFocus() {
  606.         return false;
  607.     }
  608.  
  609.     /**
  610.      * Specifies the next component to get the focus after this one,
  611.      * for example, when the tab key is pressed. Invoke this method
  612.      * to override the default focus-change sequence.
  613.      * @beaninfo
  614.      *      expert: true
  615.      * description: The next component to get focus after this one.
  616.      */
  617.     public void setNextFocusableComponent(Component aComponent) {
  618.         putClientProperty(NEXT_FOCUS,aComponent);
  619.     }
  620.  
  621.     /**
  622.      * Return the next focusable component or null if the focus manager
  623.      * should choose the next focusable component automatically
  624.      */
  625.     public Component getNextFocusableComponent() {
  626.         return (Component) getClientProperty(NEXT_FOCUS);
  627.     }
  628.  
  629.     /**
  630.      *  Set whether the receiving component can obtain the focus by
  631.      *  calling requestFocus. The default value is true.
  632.      *  Note: Setting this property to false will not prevent the focus
  633.      *  manager from setting the focus to this component, it will prevent
  634.      *  the component from getting the focus when the focus is requested
  635.      *  explicitly. Override isFocusTraversable and return false if the
  636.      *  component should never get the focus.
  637.      * @beaninfo
  638.      *      expert: true
  639.      * description: Whether the component can obtain the focus by calling requestFocus.
  640.      */
  641.     public void setRequestFocusEnabled(boolean aFlag) {
  642.         setFlag(REQUEST_FOCUS_DISABLED,(aFlag ? false:true));
  643.     }
  644.  
  645.     /** Return whether the receiving component can obtain the focus by
  646.      *  calling requestFocus
  647.      *  @see #setRequestFocusEnabled
  648.      */
  649.     public boolean isRequestFocusEnabled() {
  650.         return (getFlag(REQUEST_FOCUS_DISABLED) ? false : true);
  651.     }
  652.  
  653.     /** Set focus on the receiving component if isRequestFocusEnabled returns true **/
  654.     public void requestFocus() {
  655.  
  656.       /* someone other then the focus manager is requesting focus,
  657.      so we clear the focus manager's idea of focus history */
  658.         FocusManager focusManager = FocusManager.getCurrentManager();
  659.         if (focusManager instanceof DefaultFocusManager) 
  660.       ((DefaultFocusManager)focusManager).clearHistory();
  661.  
  662.         if(isRequestFocusEnabled()) {
  663.             super.requestFocus();
  664.         }
  665.     }
  666.  
  667.     /** Set the focus on the receiving component. This method is for focus managers, you
  668.      *  rarely want to call this method, use requestFocus() enstead.
  669.      */
  670.     public void grabFocus() {
  671.         super.requestFocus();
  672.     }
  673.  
  674.     /**
  675.      * Set the preferred size of the receiving component.
  676.      * if <code>preferredSize</code> is null, the UI will
  677.      * be asked for the preferred size
  678.      * @beaninfo
  679.      *   preferred: true
  680.      *       bound: true
  681.      * description: The preferred size of the component.
  682.      */
  683.     public void setPreferredSize(Dimension preferredSize) {
  684.     Dimension old = this.preferredSize;
  685.         this.preferredSize = preferredSize;
  686.         firePropertyChange("preferredSize", old, preferredSize);
  687.     }
  688.  
  689.  
  690.     /**
  691.      * If the preferredSize has been set to a non-null value
  692.      * just return it.  If the UI delegates getPreferredSize()
  693.      * method returns a non null then value return that, otherwise
  694.      * defer to the components layout manager.
  695.      *
  696.      * @return the value of the preferredSize property.
  697.      * @see #setPreferredSize
  698.      */
  699.     public Dimension getPreferredSize() {
  700.         if (preferredSize != null) {
  701.             return preferredSize;
  702.         }
  703.         Dimension size = null;
  704.         if (ui != null) {
  705.             size = ui.getPreferredSize(this);
  706.         }
  707.         return (size != null) ? size : super.getPreferredSize();
  708.     }
  709.  
  710.  
  711.     /**
  712.      * Sets the maximumSize of this component to a constant
  713.      * value.  Subsequent calls to getMaximumSize will always
  714.      * return this value, the components UI will not be asked
  715.      * to compute it.  Setting the maximumSize to null
  716.      * restores the default behavior.
  717.      *
  718.      * @see #getMaximumSize
  719.      * @beaninfo
  720.      *       bound: true
  721.      * description: The maximum size of the component.
  722.      */
  723.     public void setMaximumSize(Dimension maximumSize) {
  724.     Dimension old = this.maximumSize;
  725.         this.maximumSize = maximumSize;
  726.         firePropertyChange("maximumSize", old, maximumSize);
  727.     }
  728.  
  729.  
  730.     /**
  731.      * If the maximumSize has been set to a non-null value
  732.      * just return it.  If the UI delegates getMaximumSize()
  733.      * method returns a non null value then return that, otherwise
  734.      * defer to the components layout manager.
  735.      *
  736.      * @return the value of the maximumSize property.
  737.      * @see #setMaximumSize
  738.      */
  739.     public Dimension getMaximumSize() {
  740.         if (maximumSize != null) {
  741.             return maximumSize;
  742.         }
  743.         Dimension size = null;
  744.         if (ui != null) {
  745.             size = ui.getMaximumSize(this);
  746.         }
  747.         return (size != null) ? size : super.getMaximumSize();
  748.     }
  749.  
  750.  
  751.     /**
  752.      * Sets the minimumSize of this component to a constant
  753.      * value.  Subsequent calls to getMinimumSize will always
  754.      * return this value, the components UI will not be asked
  755.      * to compute it.  Setting the minimumSize to null
  756.      * restores the default behavior.
  757.      *
  758.      * @see #getMinimumSize
  759.      * @beaninfo
  760.      *       bound: true
  761.      * description: The minimum size of the component.
  762.      */
  763.     public void setMinimumSize(Dimension minimumSize) {
  764.     Dimension old = this.minimumSize;
  765.         this.minimumSize = minimumSize;
  766.         firePropertyChange("minimumSize", old, minimumSize);
  767.     }
  768.  
  769.     /**
  770.      * If the minimumSize has been set to a non-null value
  771.      * just return it.  If the UI delegates getMinimumSize()
  772.      * method returns a non null value then return that, otherwise
  773.      * defer to the components layout manager.
  774.      *
  775.      * @return the value of the minimumSize property.
  776.      * @see #setMinimumSize
  777.      */
  778.     public Dimension getMinimumSize() {
  779.         if (minimumSize != null) {
  780.             return minimumSize;
  781.         }
  782.         Dimension size = null;
  783.         if (ui != null) {
  784.             size = ui.getMinimumSize(this);
  785.         }
  786.         return (size != null) ? size : super.getMinimumSize();
  787.     }
  788.  
  789.  
  790.     /**
  791.      * Give the UI delegate an opportunity to define the precise
  792.      * shape of this component for the sake of mouse processing.
  793.      *
  794.      * @return true if this component logically contains x,y.
  795.      * @see java.awt.Component#contains(int, int)
  796.      */
  797.     public boolean contains(int x, int y) {
  798.         return (ui != null) ? ui.contains(this, x, y) : super.contains(x, y);
  799.     }
  800.  
  801.  
  802.     /**
  803.      * Sets the border of this component.  The Border object is
  804.      * responsible for defining the insets for the component
  805.      * (overriding any insets set directly on the component) and
  806.      * for optionally rendering any border decorations within the
  807.      * bounds of those insets.  Borders should be used (rather
  808.      * than insets) for creating both decorative and non-decorative
  809.      * (e.g. margins and padding) regions for a swing component.
  810.      * Compound borders can be used to nest multiple borders within a
  811.      * single component.
  812.      * <p>
  813.      * This is a bound property.
  814.      *
  815.      * @param border the border to be rendered for this component
  816.      * @see Border
  817.      * @see CompoundBorder
  818.      * @beaninfo
  819.      *        bound: true
  820.      *    preferred: true
  821.      *    attribute: visualUpdate true
  822.      *  description: The component's border.
  823.      */
  824.     public void setBorder(Border border) {
  825.         Border         oldBorder = this.border;
  826.  
  827.         this.border = border;
  828.         firePropertyChange("border", oldBorder, border);
  829.         if (border != oldBorder) {
  830.             if (border == null || oldBorder == null ||
  831.                 !(border.getBorderInsets(this).equals(oldBorder.getBorderInsets(this)))) {
  832.                 revalidate();
  833.             } 
  834.             repaint();
  835.         }
  836.     }
  837.  
  838.     /**
  839.      * Returns the border of this component or null if no border is
  840.      * currently set.
  841.      *
  842.      * @return the border object for this component
  843.      * @see #setBorder
  844.      */
  845.     public Border getBorder() {
  846.         return border;
  847.     }
  848.  
  849.     /**
  850.      * If a border has been set on this component, returns the
  851.      * border's insets, else calls super.getInsets.
  852.      *
  853.      * @return the value of the insets property.
  854.      * @see #setBorder
  855.      */
  856.     public Insets getInsets() {
  857.         if (border != null) {
  858.             return border.getBorderInsets(this);
  859.         }
  860.         return super.getInsets();
  861.     }
  862.  
  863.     /**
  864.      * Returns an Insets object containing this component's inset
  865.      * values.  The passed-in Insets object will be reused if possible.
  866.      * Calling methods cannot assume that the same object will be returned,
  867.      * however.  All existing values within this object are overwritten.
  868.      *
  869.      * @param insets the Insets object which can be reused.
  870.      * @see #getInsets
  871.      * @beaninfo
  872.      *   expert: true
  873.      */
  874.     public Insets getInsets(Insets insets) {
  875.         if (border != null) {
  876.             if (border instanceof AbstractBorder) {
  877.                 return ((AbstractBorder)border).getBorderInsets(this, insets);
  878.             } else {
  879.                 // Can't reuse border insets because the Border interface
  880.                 // can't be enhanced.
  881.                 return border.getBorderInsets(this);
  882.             }
  883.         } else {
  884.             // super.getInsets() always returns an Insets object with
  885.             // all of its value zeroed.  No need for a new object here.
  886.             insets.left = insets.top = insets.right = insets.bottom = 0;
  887.             return insets;
  888.         }
  889.     }
  890.  
  891.     /**
  892.      * Overrides <code>Container.getAlignmentY</code> to return
  893.      * the horizontal alignment.
  894.      *
  895.      * @return the value of the alignmentY property.
  896.      * @see #setAlignmentY
  897.      * @see java.awt.Component#getAlignmentY
  898.      */
  899.     public float getAlignmentY() {
  900.         return (alignmentY != null) ? alignmentY.floatValue() : super.getAlignmentY();
  901.     }
  902.  
  903.     /**
  904.      * Set the the horizontal alignment.
  905.      *
  906.      * @see #getAlignmentY
  907.      * @beaninfo
  908.      *   description: The preferred vertical alignment of the component
  909.      */
  910.     public void setAlignmentY(float alignmentY) {
  911.         this.alignmentY = new Float(alignmentY > 1.0f ? 1.0f : alignmentY < 0.0f ? 0.0f : alignmentY);
  912.     }
  913.  
  914.  
  915.     /**
  916.      * Overrides <code>Container.getAlignmentX</code> to return
  917.      * the vertical alignment.
  918.      *
  919.      * @return the value of the alignmentX property.
  920.      * @see #setAlignmentX
  921.      * @see java.awt.Component#getAlignmentX
  922.      */
  923.     public float getAlignmentX() {
  924.         return (alignmentX != null) ? alignmentX.floatValue() : super.getAlignmentX();
  925.     }
  926.  
  927.     /**
  928.      * Set the the vertical alignment.
  929.      *
  930.      * @see #getAlignmentX
  931.      * @beaninfo
  932.      *   description: The preferred horizontal alignment of the component
  933.      */
  934.     public void setAlignmentX(float alignmentX) {
  935.         this.alignmentX = new Float(alignmentX > 1.0f ? 1.0f : alignmentX < 0.0f ? 0.0f : alignmentX);
  936.     }
  937.  
  938.  
  939.     /**
  940.      * Returns this component's graphics context, which lets you draw
  941.      * on a component. Use this method get a Graphics object and
  942.      * then invoke oeprations on that object to draw on the component.
  943.      */
  944.     public Graphics getGraphics() {
  945.         if (shouldDebugGraphics() != 0) {
  946.             DebugGraphics graphics = new DebugGraphics(super.getGraphics(),
  947.                                                        this);
  948.             return graphics;
  949.         }
  950.         return super.getGraphics();
  951.     }
  952.  
  953.  
  954.     /** Enables or disables diagnostic information about every graphics
  955.       * operation performed within the component or one of its children. The
  956.       * value of <b>debugOptions</b> determines how the component should
  957.       * display this information:
  958.       * <ul>
  959.       * <li>DebugGraphics.LOG_OPTION - causes a text message to be printed.
  960.       * <li>DebugGraphics.FLASH_OPTION - causes the drawing to flash several
  961.       * times.
  962.       * <li>DebugGraphics.BUFFERED_OPTION - creates an ExternalWindow that
  963.       * displays the operations performed on the View's offscreen buffer.
  964.       * </ul>
  965.       * <b>debug</b> is bitwise OR'd into the current value.
  966.       * DebugGraphics.NONE_OPTION disables debugging.
  967.       * A value of 0 causes no changes to the debugging options.
  968.       * @beaninfo
  969.       *   preferred: true
  970.       * description: Diagnostic options for graphics operations.
  971.       */
  972.     public void setDebugGraphicsOptions(int debugOptions) {
  973.         DebugGraphics.setDebugOptions(this, debugOptions);
  974.     }
  975.  
  976.     /** Returns the state of graphics debugging.
  977.       * @see #setDebugGraphicsOptions
  978.       */
  979.     public int getDebugGraphicsOptions() {
  980.         return DebugGraphics.getDebugOptions(this);
  981.     }
  982.  
  983.  
  984.     /**
  985.      * Returns <b>true</b> if debug information is enabled for this JComponent
  986.      * or one if its parents.
  987.      */
  988.     int shouldDebugGraphics() {
  989.         return DebugGraphics.shouldComponentDebug(this);
  990.     }
  991.  
  992.     /**
  993.      * Register a new keyboard action.
  994.      * <b>anAction</b> will be invoked if a key event matching <b>aKeyStroke</b> occurs
  995.      * and <b>aCondition</b> is verified. The KeyStroke object defines a
  996.      * particular combination of a keyboard key and one or more modifiers
  997.      * (alt, shift, ctrl, meta).
  998.      * <p>
  999.      * The <b>aCommand</b> will be set in the delivered event if specified.
  1000.      * <p>
  1001.      * The Condition can be one of:
  1002.      * <blockquote>
  1003.      * <DL>
  1004.      * <DT>WHEN_FOCUSED
  1005.      * <DD>The action will be invoked only when the keystroke occurs
  1006.      *     while the component has the focus.
  1007.      * <DT>WHEN_IN_FOCUSED_WINDOW
  1008.      * <DD>The action will be invoked when the keystroke occurs while
  1009.      *     the component has the focus or if the component is in the
  1010.      *     window that has the focus. Note that the component need not
  1011.      *     be an immediate descendent of the window -- it can be
  1012.      *     anywhere in the window's containment hierarchy. In other
  1013.      *     words, whenever <em>any</em> component in the window has the focus,
  1014.      *     the action registered with this component is invoked.
  1015.      * <DT>WHEN_ANCESTOR_OF_FOCUSED_COMPONENT
  1016.      * <DD>The action will be invoked when the keystroke occurs while the
  1017.      *     component has the focus or if the component is an ancestor of
  1018.      *     the component that has the focus.
  1019.      * </DL>
  1020.      * </blockquote>
  1021.      * <p>
  1022.      * The combination of keystrokes and conditions lets you define high
  1023.      * level (semantic) action events for a specified keystroke+modifier
  1024.      * combination (using the KeyStroke class) and direct to a parent or
  1025.      * child of a component that has the focus, or to the component itself.
  1026.      * In other words, in any hierarchical structure of components, an
  1027.      * arbitrary key-combination can be immediately directed to the
  1028.      * appropriate component in the hierarchy, and cause a specific method
  1029.      * to be invoked (usually by way of adapter objects).
  1030.      * <p>
  1031.      * If an action has already been registered for the receiving
  1032.      * container, with the same charCode and the same modifiers,
  1033.      * <b>anAction</b> will replace the action.
  1034.      *
  1035.      * @see KeyStroke
  1036.      */
  1037.     public void registerKeyboardAction(ActionListener anAction,String aCommand,KeyStroke aKeyStroke,int aCondition) {
  1038.       Hashtable bindings;
  1039.       boolean firstKeyboardAction = false;
  1040.  
  1041.       synchronized(this) {
  1042.         bindings = (Hashtable) getClientProperty(KEYBOARD_BINDINGS_KEY);
  1043.         if(bindings == null) {
  1044.           bindings = new Hashtable();
  1045.           putClientProperty(KEYBOARD_BINDINGS_KEY,bindings);
  1046.           firstKeyboardAction = true;
  1047.         }
  1048.       }
  1049.  
  1050.       synchronized(bindings) {
  1051.         bindings.put(aKeyStroke,new KeyboardBinding(anAction,aCommand,aKeyStroke,aCondition));
  1052.       }
  1053.  
  1054.       /* This is the first time a keyboard binding is added, let's order
  1055.        * keyboard events...
  1056.        * ALERT: we need to enable events. Adding a listener will not work since
  1057.        *        we want our listener to be after all other listeners.
  1058.        */
  1059.       if(firstKeyboardAction) {
  1060.         enableEvents(AWTEvent.KEY_EVENT_MASK);
  1061.       }
  1062.  
  1063.         if (getParent() != null && aCondition == WHEN_IN_FOCUSED_WINDOW) {
  1064.       registerWithKeyboardManager(aKeyStroke);
  1065.     }
  1066.    
  1067.     }
  1068.  
  1069.     void registerWithKeyboardManager(KeyStroke aKeyStroke) {
  1070.  
  1071.         KeyboardManager.getCurrentManager().registerKeyStroke(aKeyStroke, this);
  1072.  
  1073.     }
  1074.  
  1075.     void unregisterWithKeyboardManager(KeyStroke aKeyStroke) {
  1076.       KeyboardManager.getCurrentManager().unregisterKeyStroke(aKeyStroke, this);
  1077.     }
  1078.  
  1079.     /**
  1080.      *  Calls registerKeyboardAction(ActionListener,String,KeyStroke,condition) with a null command.
  1081.      */
  1082.     public void registerKeyboardAction(ActionListener anAction,KeyStroke aKeyStroke,int aCondition) {
  1083.         registerKeyboardAction(anAction,null,aKeyStroke,aCondition);
  1084.     }
  1085.  
  1086.     private Hashtable keyboardBindings() {
  1087.         Hashtable bindings;
  1088.         synchronized(this) {
  1089.             bindings = (Hashtable) getClientProperty(KEYBOARD_BINDINGS_KEY);
  1090.         }
  1091.         return bindings;
  1092.     }
  1093.  
  1094.     /**
  1095.      * Unregister a keyboard action.
  1096.      *
  1097.      * @see #registerKeyboardAction
  1098.      */
  1099.     public void unregisterKeyboardAction(KeyStroke aKeyStroke) {
  1100.         Hashtable bindings = keyboardBindings();
  1101.     KeyboardBinding aBinding;
  1102.  
  1103.         if(bindings == null)
  1104.             return;
  1105.         synchronized(bindings) {
  1106.             aBinding = (KeyboardBinding)bindings.remove(aKeyStroke);
  1107.         }
  1108.  
  1109.         if(bindings.size() == 0) {
  1110.             /** ALERT. We need a way to disable keyboard events only if there is no
  1111.              *        keyboard listener.
  1112.              */
  1113.         }
  1114.  
  1115.     if ( aBinding != null && aBinding.condition ==  WHEN_IN_FOCUSED_WINDOW) {
  1116.         unregisterWithKeyboardManager(aKeyStroke);
  1117.     }
  1118.     }
  1119.  
  1120.     /**
  1121.      * Return the KeyStrokes that will initiate registered actions.
  1122.      *
  1123.      * @return an array of KeyStroke objects
  1124.      * @see #registerKeyboardAction
  1125.      */
  1126.     public KeyStroke[] getRegisteredKeyStrokes() {
  1127.         Hashtable bindings = keyboardBindings();
  1128.         KeyStroke result[];
  1129.         int i;
  1130.         Enumeration keys;
  1131.  
  1132.         if(bindings == null)
  1133.             return new KeyStroke[0];
  1134.         synchronized(bindings) {
  1135.             result = new KeyStroke[bindings.size()];
  1136.             i = 0;
  1137.             keys = bindings.keys();
  1138.             while(keys.hasMoreElements())
  1139.                 result[i++] = (KeyStroke) keys.nextElement();
  1140.         }
  1141.         return result;
  1142.     }
  1143.  
  1144.     /**
  1145.      * Return the condition that determines whether a registered action
  1146.      * occurs in response to the specified keystroke.
  1147.      *
  1148.      * @return the action-keystroke condition
  1149.      * @see #registerKeyboardAction
  1150.      */
  1151.     public int getConditionForKeyStroke(KeyStroke aKeyStroke) {
  1152.         Hashtable bindings = keyboardBindings();
  1153.         if(bindings == null)
  1154.             return UNDEFINED_CONDITION;
  1155.         synchronized(bindings) {
  1156.             KeyboardBinding kb = (KeyboardBinding) bindings.get(aKeyStroke);
  1157.             if(kb != null) {
  1158.                 return kb.getCondition();
  1159.             }
  1160.         }
  1161.         return UNDEFINED_CONDITION;
  1162.     }
  1163.  
  1164.     /**
  1165.      * Return the object that will perform the action registered for a
  1166.      * given keystroke.
  1167.      *
  1168.      * @return the ActionListener object invoked when the keystroke occurs
  1169.      * @see #registerKeyboardAction
  1170.      */
  1171.     public ActionListener getActionForKeyStroke(KeyStroke aKeyStroke) {
  1172.         Hashtable bindings = keyboardBindings();
  1173.  
  1174.         if(bindings == null)
  1175.             return null;
  1176.         synchronized(bindings) {
  1177.             KeyboardBinding kb = (KeyboardBinding) bindings.get(aKeyStroke);
  1178.             if(kb != null) {
  1179.                 return kb.getAction();
  1180.             }
  1181.         }
  1182.         return null;
  1183.     }
  1184.  
  1185.  
  1186.  
  1187.     /**
  1188.      * Unregister all keyboard actions
  1189.      *
  1190.      * @see #registerKeyboardAction
  1191.      */
  1192.     public void resetKeyboardActions() {
  1193.       synchronized(this) {
  1194.           Hashtable bindings = (Hashtable) getClientProperty(KEYBOARD_BINDINGS_KEY);
  1195.           if(bindings != null) {
  1196.               bindings.clear();
  1197.           }
  1198.       }
  1199.       /* ALERT. We need a way to disable keyboard events only if there is no
  1200.        *        keyboard listener.
  1201.        */
  1202.     }
  1203.  
  1204.     /**
  1205.      * Request the focus for the component that should have the focus
  1206.      * by default. The default implementation will recursively request
  1207.      * the focus on the first component that is focus-traversable.
  1208.      *
  1209.      * @return false if the focus has not been set, otherwise
  1210.      *         return true
  1211.      */
  1212.     public boolean requestDefaultFocus() {
  1213.         Component ca[] = getComponents();
  1214.         int i;
  1215.         for(i=0 ; i < ca.length ; i++) {
  1216.             if(ca[i].isFocusTraversable()) {
  1217.                 if(ca[i] instanceof JComponent) {
  1218.                     ((JComponent)ca[i]).grabFocus();
  1219.                 } else {
  1220.                     ca[i].requestFocus();
  1221.                 }
  1222.                 return true;
  1223.             }
  1224.             if(ca[i] instanceof JComponent && !((JComponent)ca[i]).isManagingFocus()) {
  1225.                 if(((JComponent)(ca[i])).requestDefaultFocus()) {
  1226.                     return true;
  1227.                 }
  1228.             }
  1229.         }
  1230.         return false;
  1231.     }
  1232.  
  1233.     /**
  1234.      * Makes the component visible or invisible.
  1235.      * Overrides <code>Component.setVisible</code>.
  1236.      * 
  1237.      * @param aFlag  true to make the component visible
  1238.      */
  1239.     public void setVisible(boolean aFlag) {
  1240.         if(aFlag != isVisible()) {
  1241.             super.setVisible(aFlag);
  1242.             Container parent = getParent();
  1243.             if(parent != null) {
  1244.                 Rectangle r = getBounds();
  1245.                 parent.repaint(r.x,r.y,r.width,r.height);
  1246.             }
  1247.  
  1248.             if (accessibleContext != null) {
  1249.             if (aFlag) {
  1250.             accessibleContext.firePropertyChange(
  1251.                 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  1252.                 null, AccessibleState.VISIBLE);
  1253.             } else {
  1254.             accessibleContext.firePropertyChange(
  1255.                 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  1256.                 AccessibleState.VISIBLE, null);
  1257.             }
  1258.             }
  1259.         }
  1260.     }
  1261.  
  1262.     /**
  1263.      * Sets whether or not this component is enabled.
  1264.      * A component which is enabled may respond to user input,
  1265.      * while a component which is not enabled cannot respond to 
  1266.      * user input.  Some components may alter their visual
  1267.      * representation when they are disabled in order to 
  1268.      * provide feedback to the user that they cannot take input.
  1269.      *
  1270.      * @see java.awt.Component#isEnabled
  1271.      *
  1272.      * @beaninfo
  1273.      *    preferred: true
  1274.      *        bound: true
  1275.      *    attribute: visualUpdate true
  1276.      *  description: The enabled state of the component
  1277.      */
  1278.     public void setEnabled(boolean enabled) {
  1279.         boolean oldEnabled = isEnabled();
  1280.         super.setEnabled(enabled);
  1281.     if (!enabled && hasFocus()) {
  1282.         FocusManager.getCurrentManager().focusPreviousComponent(this);
  1283.     }
  1284.         firePropertyChange("enabled", oldEnabled, enabled);
  1285.         if (enabled != oldEnabled) {
  1286.             repaint();
  1287.         }
  1288.     }
  1289.  
  1290.     /**
  1291.      * Sets the foreground color of this component.
  1292.      *
  1293.      * @see java.awt.Component#getForeground
  1294.      *
  1295.      * @beaninfo
  1296.      *    preferred: true
  1297.      *        bound: true
  1298.      *    attribute: visualUpdate true
  1299.      *  description: The foreground color of the component.
  1300.      */
  1301.     public void setForeground(Color fg) {
  1302.         Color oldFg = getForeground();
  1303.         super.setForeground(fg);
  1304.         // foreground already bound in AWT1.2
  1305.         if (!SwingUtilities.is1dot2) {
  1306.             firePropertyChange("foreground", oldFg, fg);
  1307.         }
  1308.         if (fg != oldFg) {
  1309.             repaint();
  1310.         }
  1311.     }
  1312.  
  1313.     /**
  1314.      * Sets the background color of this component.
  1315.      *
  1316.      * @see java.awt.Component#getBackground
  1317.      *
  1318.      * @beaninfo
  1319.      *    preferred: true
  1320.      *        bound: true
  1321.      *    attribute: visualUpdate true
  1322.      *  description: The background color of the component.
  1323.      */
  1324.     public void setBackground(Color bg) {
  1325.         Color oldBg = getBackground();
  1326.         super.setBackground(bg);
  1327.         // background already bound in AWT1.2
  1328.         if (!SwingUtilities.is1dot2) {
  1329.             firePropertyChange("background", oldBg, bg);
  1330.         }
  1331.         if (bg != oldBg) {
  1332.             repaint();
  1333.         }
  1334.     }
  1335.  
  1336.     /**
  1337.      * Sets the font for this component.
  1338.      *
  1339.      * @see java.awt.Component#getFont
  1340.      *
  1341.      * @beaninfo
  1342.      *    preferred: true
  1343.      *        bound: true
  1344.      *    attribute: visualUpdate true
  1345.      *  description: The font for the component.
  1346.      */
  1347.     public void setFont(Font font) {
  1348.         Font oldFont = getFont();
  1349.         super.setFont(font);
  1350.         // font already bound in AWT1.2
  1351.         if (!SwingUtilities.is1dot2) {
  1352.             firePropertyChange("font", oldFont, font);
  1353.         }
  1354.         if (font != oldFont) {
  1355.             revalidate();
  1356.         }
  1357.     }
  1358.         
  1359.  
  1360.     /**
  1361.      * Identifies whether or not this component can receive the focus.
  1362.      * A disabled button, for example, would return false.
  1363.      *
  1364.      * @return true if this component can receive the focus
  1365.      */
  1366.     public boolean isFocusTraversable() {
  1367.       boolean result = false;
  1368.       Hashtable bindings;
  1369.  
  1370.       synchronized(this) {
  1371.         bindings = (Hashtable) getClientProperty(KEYBOARD_BINDINGS_KEY);
  1372.       }
  1373.       if(bindings != null) {
  1374.         synchronized(bindings) {
  1375.             Enumeration keys = bindings.keys();
  1376.             KeyboardBinding b;
  1377.  
  1378.             while(keys.hasMoreElements()) {
  1379.                 b = (KeyboardBinding) bindings.get(keys.nextElement());
  1380.                 if(b.getCondition() == WHEN_FOCUSED) {
  1381.                     result = true;
  1382.                     break;
  1383.                 }
  1384.             }
  1385.         }
  1386.       }
  1387.       return result;
  1388.     }
  1389.  
  1390.     protected void processFocusEvent(FocusEvent e) {
  1391.         switch(e.getID()) {
  1392.           case FocusEvent.FOCUS_GAINED:
  1393.               setFlag(HAS_FOCUS, true);
  1394.               break;
  1395.           case FocusEvent.FOCUS_LOST:
  1396.               setFlag(HAS_FOCUS, false);
  1397.               break;
  1398.         }
  1399.  
  1400.         // Call super *after* setting flag, in case listener calls paint.
  1401.         super.processFocusEvent(e);
  1402.     }
  1403.  
  1404.     /**
  1405.      * Process any key events that the component itself
  1406.      * recognizes.  This will be called after the focus
  1407.      * manager and any interested listeners have been
  1408.      * given a chance to steal away the event.  This
  1409.      * method will only be called is the event has not
  1410.      * yet been consumed.  This method is called prior
  1411.      * to the keyboard UI logic.
  1412.      * <p>
  1413.      * This is implemented to do nothing.  Subclasses would
  1414.      * normally override this method if they process some
  1415.      * key events themselves.  If the event is processed,
  1416.      * it should be consumed.
  1417.      */
  1418.     protected void processComponentKeyEvent(KeyEvent e) {
  1419.     }
  1420.  
  1421.     /** Override processKeyEvent to process events **/
  1422.     protected void processKeyEvent(KeyEvent e) {
  1423.       // focus manager gets to steal the event if it wants it.
  1424.       boolean result;
  1425.       boolean shouldProcessKey = false;
  1426.       if(FocusManager.isFocusManagerEnabled()) {
  1427.           FocusManager focusManager = FocusManager.getCurrentManager();
  1428.           focusManager.processKeyEvent(this,e);
  1429.           if(e.isConsumed()) {
  1430.               return;
  1431.           }
  1432.       }
  1433.  
  1434.       // This gives the key event listeners a crack at the event
  1435.       super.processKeyEvent(e);
  1436.  
  1437.       // give the component itself a crack at the event
  1438.       if (! e.isConsumed()) {
  1439.           processComponentKeyEvent(e);
  1440.       }
  1441.  
  1442.       if(e.getID() == KeyEvent.KEY_PRESSED) {
  1443.           shouldProcessKey = true;
  1444.           if(!KeyboardState.keyIsPressed(e.getKeyCode()))
  1445.               KeyboardState.registerKeyPressed(e.getKeyCode());
  1446.       } else if(e.getID() == KeyEvent.KEY_RELEASED) {
  1447.           if(KeyboardState.keyIsPressed(e.getKeyCode())) {
  1448.               shouldProcessKey = true;
  1449.               KeyboardState.registerKeyReleased(e.getKeyCode());
  1450.           }
  1451.       } else if(e.getID() == KeyEvent.KEY_TYPED) {
  1452.           shouldProcessKey = true;
  1453.       }
  1454.  
  1455.       if(e.isConsumed()) {
  1456.         return;
  1457.       }
  1458.  
  1459.       // (PENDING) Hania & Steve - take out this block?  Do we need to do this pressed stuff?
  1460.       // And, shouldProcessKey, do we need it?
  1461.       if(shouldProcessKey && e.getID() == KeyEvent.KEY_PRESSED) {
  1462.         result = processKeyBindings(e,true);
  1463.         if(result)
  1464.           e.consume();
  1465.       } else if(shouldProcessKey && e.getID() == KeyEvent.KEY_RELEASED) {
  1466.           result = processKeyBindings(e,false);
  1467.           if(result) {
  1468.               e.consume();
  1469.           }
  1470.       } else if(shouldProcessKey && e.getID() == KeyEvent.KEY_TYPED) {
  1471.           result = processKeyBindings(e,false);
  1472.           if(result) {
  1473.               e.consume();
  1474.           }
  1475.       }
  1476.     }
  1477.  
  1478.     KeyboardBinding bindingForKeyStroke(KeyStroke ks,int condition) {
  1479.         Hashtable bindings;
  1480.         KeyboardBinding b;
  1481.         KeyboardBinding result = null;
  1482.  
  1483.         // synchronized(this) {
  1484.             bindings = (Hashtable) getClientProperty(KEYBOARD_BINDINGS_KEY);
  1485.         // }
  1486.         if(bindings != null) {
  1487.             // synchronized(bindings) {
  1488.                 b = (KeyboardBinding) bindings.get(ks);
  1489.                 // System.out.println("Bindings are " + bindings);
  1490.                 if(b != null) {
  1491.                     ActionListener action = b.getAction();
  1492.                     if((action instanceof Action) && !(((Action)action).isEnabled()))
  1493.                         action = null;
  1494.                     if(action != null) {
  1495.                         switch(b.getCondition()) {
  1496.                         case WHEN_FOCUSED:
  1497.                             if(condition == WHEN_FOCUSED)
  1498.                                 result = b;
  1499.                             break;
  1500.                         case WHEN_ANCESTOR_OF_FOCUSED_COMPONENT:
  1501.                             if(condition == WHEN_FOCUSED ||
  1502.                                condition == WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
  1503.                                 result = b;
  1504.                             break;
  1505.                         case WHEN_IN_FOCUSED_WINDOW:
  1506.                             if(condition == WHEN_FOCUSED ||
  1507.                                condition == WHEN_IN_FOCUSED_WINDOW ||
  1508.                                condition == WHEN_ANCESTOR_OF_FOCUSED_COMPONENT)
  1509.                                 result = b;
  1510.                             break;
  1511.                         }
  1512.                     }
  1513.                 }
  1514.             // }
  1515.         }
  1516.         return result;
  1517.     }
  1518.  
  1519.     boolean processKeyBinding(KeyEvent e,int condition,boolean pressed) {
  1520.         Hashtable bindings;
  1521.         int i,c;
  1522.         boolean onKeyRelease = (pressed?false:true);
  1523.         KeyboardBinding binding = null;
  1524.         KeyStroke ks;
  1525.  
  1526.         if(isEnabled()) {
  1527.             if(e.getID() == KeyEvent.KEY_TYPED) {
  1528.                 binding = bindingForKeyStroke((ks=KeyStroke.getKeyStroke(e.getKeyChar())),condition);
  1529.             } else {
  1530.                 binding = bindingForKeyStroke((ks=KeyStroke.getKeyStroke(e.getKeyCode(),e.getModifiers(),
  1531.                                                                      onKeyRelease)), condition);
  1532.             }
  1533.             //System.out.println("e=" + e + "ks is " + ks);
  1534.             if(binding != null) {
  1535.                 ActionListener listener = binding.getAction();
  1536.                 if(listener != null) {
  1537.                     listener.actionPerformed(new ActionEvent(this,ActionEvent.ACTION_PERFORMED,binding.getCommand()));
  1538.                     return true;
  1539.                 }
  1540.             }
  1541.         }
  1542.  
  1543.         return false;
  1544.     }
  1545.  
  1546.     boolean processKeyBindings(KeyEvent e,boolean pressed) {
  1547.       Container parent;
  1548.  
  1549.       /* Do we have a key binding for e? */
  1550.       if(processKeyBinding(e,WHEN_FOCUSED,pressed))
  1551.         return true;
  1552.  
  1553.       /* We have no key binding. Let's try the path from our parent to the window excluded
  1554.        * We store the path components so we can avoid asking the same component twice.
  1555.        */
  1556.       parent = this.getParent();
  1557.       while(parent != null && !(parent instanceof Window) && !(parent instanceof Applet) && !(parent instanceof JInternalFrame)) {
  1558.     // maybe generalize from JInternalFrame (like isFocusCycleRoot).
  1559.       if(parent instanceof JComponent) {
  1560.           if(((JComponent)parent).processKeyBinding(e,WHEN_ANCESTOR_OF_FOCUSED_COMPONENT,pressed))
  1561.         return true;
  1562.       }
  1563.       parent = parent.getParent();
  1564.       }
  1565.  
  1566.       /* No components between the focused component and the window is actually interested
  1567.        * by the key event. Let's try the other JComponent in this window.
  1568.        */
  1569.       if(parent != null) {
  1570.         return JComponent.processKeyBindingsForAllComponents(e,parent,pressed);
  1571.       }
  1572.       return false;
  1573.     }
  1574.  
  1575.     static boolean processKeyBindingsForAllComponents(KeyEvent e,Container container, boolean pressed) {
  1576.  
  1577.       return KeyboardManager.getCurrentManager().fireKeyboardAction(e, pressed, container);
  1578.  
  1579.     /*  int i;
  1580.       Component subComponents[];
  1581.  
  1582.       if(!container.isVisible() || !container.isEnabled()) {
  1583.       return false;
  1584.       }
  1585.  
  1586.       if(container instanceof JComponent && !alreadyProcessed.contains(container)) {
  1587.           if(((JComponent)container).processKeyBinding(e,WHEN_IN_FOCUSED_WINDOW,pressed))
  1588.           return true;
  1589.       }
  1590.  
  1591.       subComponents = container.getComponents();
  1592.       for(i=0 ; i < subComponents.length ; i++) {
  1593.       if(subComponents[i].isVisible() && subComponents[i].isEnabled()) {
  1594.           if(subComponents[i] instanceof Container) {
  1595.           if(processKeyBindingsForAllComponents(e,(Container)subComponents[i],alreadyProcessed,pressed))
  1596.             return true;
  1597.           }
  1598.       }
  1599.       }
  1600.       return false;*/
  1601.     }
  1602.  
  1603.     /**
  1604.      * Registers the text to display in a tool tip.
  1605.      * The text displays when the cursor lingers over the component.
  1606.      * <p>
  1607.      * See <a href="http://java.sun.com/docs/books/tutorial/ui/swing/tooltip.html">How to Use Tool Tips</a>
  1608.      * in <a href="http://java.sun.com/Series/Tutorial/index.html"><em>The Java Tutorial</em></a>
  1609.      * for further documentation.
  1610.      *
  1611.      * @param text  The string to display. If the text is null,
  1612.      *              the tool tip is turned off for this component.
  1613.      * @see #TOOL_TIP_TEXT_KEY
  1614.      * @beaninfo
  1615.      *   preferred: true
  1616.      * description: The text to display in a tool tip.
  1617.      */
  1618.     public void setToolTipText(String text) {
  1619.         putClientProperty(TOOL_TIP_TEXT_KEY, text);
  1620.         ToolTipManager toolTipManager = ToolTipManager.sharedInstance();
  1621.         if (text != null) {
  1622.             toolTipManager.registerComponent(this);
  1623.         } else {
  1624.             toolTipManager.unregisterComponent(this);
  1625.         }
  1626.     }
  1627.  
  1628.     /**
  1629.      * Return the tooltip string that has been set with setToolTipText()
  1630.      *
  1631.      * @return the text of the tool tip
  1632.      * @see #TOOL_TIP_TEXT_KEY
  1633.      */
  1634.     public String getToolTipText() {
  1635.         return (String)getClientProperty(TOOL_TIP_TEXT_KEY);
  1636.     }
  1637.  
  1638.  
  1639.     /**
  1640.      * Returns the string to be used as the tooltip for <i>event</i>.  By default
  1641.      * this returns any string set using setToolTipText().  If a component provides
  1642.      * more extensize API to support differing tooltips at different locations,
  1643.      * this method should be overridden.
  1644.      */
  1645.     public String getToolTipText(MouseEvent event) {
  1646.         return getToolTipText();
  1647.     }
  1648.  
  1649.     /**
  1650.      * Return the tooltip location in the receiving component coordinate system
  1651.      * If null is returned, Swing will choose a location.
  1652.      * The default implementation returns null.
  1653.      *
  1654.      * @param event  the MouseEvent that caused the ToolTipManager to
  1655.      *               show the tooltip.
  1656.      */
  1657.     public Point getToolTipLocation(MouseEvent event) {
  1658.         return null;
  1659.     }
  1660.  
  1661.  
  1662.     /**
  1663.      * Returns the instance of JToolTip that should be used to display the tooltip.
  1664.      * Components typically would not override this method, but it can be used to
  1665.      * cause different tooltips to be displayed differently.
  1666.      */
  1667.     public JToolTip createToolTip() {
  1668.         JToolTip tip = new JToolTip();
  1669.         tip.setComponent(this);
  1670.         return tip;
  1671.     }
  1672.  
  1673.     /**
  1674.      * Forwards the <b>scrollRectToVisible()</b> message to the JComponent's
  1675.      * parent. Components that can service the request, such as a JViewport,
  1676.      * override this method and perform the scrolling.
  1677.      *
  1678.      * @see JViewport
  1679.      */
  1680.     public void scrollRectToVisible(Rectangle aRect) {
  1681.         Container parent;
  1682.         int dx = getX(), dy = getY();
  1683.  
  1684.         for (parent = getParent();
  1685.                  !(parent == null) &&
  1686.                  !(parent instanceof JComponent) &&
  1687.                  !(parent instanceof CellRendererPane);
  1688.              parent = parent.getParent()) {
  1689.              Rectangle bounds = parent.getBounds();
  1690.  
  1691.              dx += bounds.x;
  1692.              dy += bounds.y;
  1693.         }
  1694.  
  1695.         if (!(parent == null) && !(parent instanceof CellRendererPane)) {
  1696.             aRect.x += dx;
  1697.             aRect.y += dy;
  1698.             ((JComponent)parent).scrollRectToVisible(aRect);
  1699.             aRect.x -= dx;
  1700.             aRect.y -= dy;
  1701.         }
  1702.     }
  1703.  
  1704.     /**
  1705.      * If <i>true</i> this component will automatically scroll its contents when
  1706.      * dragged, if contained in a component that supports scrolling, such as
  1707.      * JViewport
  1708.      *
  1709.      * @see JViewport
  1710.      * @see #getAutoscrolls
  1711.      *
  1712.      * @beaninfo
  1713.      *      expert: true
  1714.      * description: Whether this component automatically scrolls its contents when dragged.
  1715.      */
  1716.     public void setAutoscrolls(boolean autoscrolls) {
  1717.         if (autoscrolls) {
  1718.             if (autoscroller == null) {
  1719.                 autoscroller = new Autoscroller(this);
  1720.             }
  1721.         } else {
  1722.             if (autoscroller != null) {
  1723.                 autoscroller.stop();
  1724.                 autoscroller = null;
  1725.             }
  1726.         }
  1727.     }
  1728.  
  1729.     /**
  1730.      * Returns <i>true</i> if this component automatically scrolls its
  1731.      * contents when dragged, (when contained in a component that supports
  1732.      * scrolling, like JViewport
  1733.      *
  1734.      * @see JViewport
  1735.      * @see #setAutoscrolls
  1736.      */
  1737.     public boolean getAutoscrolls() {
  1738.         return autoscroller != null;
  1739.     }
  1740.  
  1741.  
  1742.     protected void processMouseMotionEvent(MouseEvent e) {
  1743.         boolean dispatch = true;
  1744.         if (autoscroller != null) {
  1745.             if (e.getID() == MouseEvent.MOUSE_DRAGGED) {
  1746.                 // We don't want to do the drags when the mouse moves if we're
  1747.                 // autoscrolling.  It makes it feel spastic.
  1748.                 dispatch = !autoscroller.timer.isRunning();
  1749.                 autoscroller.mouseDragged(e);
  1750.             }
  1751.         }
  1752.         if (dispatch) {
  1753.             super.processMouseMotionEvent(e);
  1754.         }
  1755.     }
  1756.  
  1757.     // Inner classes can't get at this method from a super class
  1758.     void superProcessMouseMotionEvent(MouseEvent e) {
  1759.         super.processMouseMotionEvent(e);
  1760.     }
  1761.  
  1762.     static class KeyboardBinding implements Serializable {
  1763.         ActionListener   action;
  1764.         String           command;
  1765.         KeyStroke keyStroke;
  1766.         int        condition;
  1767.  
  1768.         KeyboardBinding(ActionListener action,String aCommand,KeyStroke aKeyStroke,int condition) {
  1769.             this.action     = action;
  1770.             this.command    = aCommand;
  1771.             this.keyStroke  = aKeyStroke;
  1772.             this.condition  = condition;
  1773.         }
  1774.  
  1775.         ActionListener getAction() {
  1776.             return action;
  1777.         }
  1778.  
  1779.         String getCommand() {
  1780.             return command;
  1781.         }
  1782.  
  1783.         KeyStroke getKeyStroke() {
  1784.             return keyStroke;
  1785.         }
  1786.  
  1787.         int getCondition() {
  1788.             return condition;
  1789.         }
  1790.  
  1791.         public String toString() {
  1792.             return "KeyBinding ("+action+","+keyStroke+","+condition+")";
  1793.         }
  1794.     }
  1795.  
  1796.     // This class is used by the KeyboardState class to provide a single
  1797.     // instance which can be stored in the AppContext.
  1798.     static final class IntVector {
  1799.         int array[] = null;
  1800.         int count = 0;
  1801.         int capacity = 0;
  1802.  
  1803.         int size() {
  1804.             return count;
  1805.         }
  1806.  
  1807.         int elementAt(int index) {
  1808.             return array[index];
  1809.         }
  1810.  
  1811.         void addElement(int value) {
  1812.             if (count == capacity) {
  1813.                 capacity = (capacity + 2) * 2;
  1814.                 int[] newarray = new int[capacity];
  1815.                 if (count > 0) {
  1816.                     System.arraycopy(array, 0, newarray, 0, count);
  1817.                 }
  1818.                 array = newarray;
  1819.             }
  1820.             array[count++] = value;
  1821.         }
  1822.  
  1823.         void setElementAt(int value, int index) {
  1824.             array[index] = value;
  1825.         }
  1826.     }
  1827.  
  1828.     static class KeyboardState implements Serializable {
  1829.         private static final Object keyCodesKey =
  1830.             JComponent.KeyboardState.class;
  1831.  
  1832.         // Get the array of key codes from the AppContext.
  1833.         static IntVector getKeyCodeArray() {
  1834.             IntVector iv =
  1835.                 (IntVector)SwingUtilities.appContextGet(keyCodesKey);
  1836.             if (iv == null) {
  1837.                 iv = new IntVector();
  1838.                 SwingUtilities.appContextPut(keyCodesKey, iv);
  1839.             }
  1840.             return iv;
  1841.         }
  1842.  
  1843.         static void registerKeyPressed(int keyCode) {
  1844.             IntVector kca = getKeyCodeArray();
  1845.             int count = kca.size();
  1846.             int i;
  1847.             for(i=0;i<count;i++) {
  1848.                 if(kca.elementAt(i) == -1){
  1849.                     kca.setElementAt(keyCode, i);
  1850.                     return;
  1851.                 }
  1852.             }
  1853.             kca.addElement(keyCode);
  1854.         }
  1855.  
  1856.         static void registerKeyReleased(int keyCode) {
  1857.             IntVector kca = getKeyCodeArray();
  1858.             int count = kca.size();
  1859.             int i;
  1860.             for(i=0;i<count;i++) {
  1861.                 if(kca.elementAt(i) == keyCode) {
  1862.                     kca.setElementAt(-1, i);
  1863.                     return;
  1864.                 }
  1865.             }
  1866.         }
  1867.  
  1868.         static boolean keyIsPressed(int keyCode) {
  1869.             IntVector kca = getKeyCodeArray();
  1870.             int count = kca.size();
  1871.             int i;
  1872.             for(i=0;i<count;i++) {
  1873.                 if(kca.elementAt(i) == keyCode) {
  1874.                     return true;
  1875.                 }
  1876.             }
  1877.             return false;
  1878.         }
  1879.     }
  1880.  
  1881.  
  1882.     /**
  1883.      * --- Accessibility Support ---
  1884.      *
  1885.      *  JComponent will contain all of the methods in interface Accessible,
  1886.      *  though it won't actally implement the interface - that will be up
  1887.      *  to the individual objects which extend JComponent.
  1888.      */
  1889.  
  1890.     protected AccessibleContext accessibleContext = null;
  1891.  
  1892.     /**
  1893.      * Get the AccessibleContext associated with this JComponent
  1894.      *
  1895.      * @return the AccessibleContext of this JComponent
  1896.      */
  1897.     public AccessibleContext getAccessibleContext() {
  1898.         return accessibleContext;
  1899.     }
  1900.  
  1901.     /**
  1902.      * Inner class of JComponent used to provide default support for
  1903.      * accessibility.  This class is not meant to be used directly by
  1904.      * application developers, but is instead meant only to be
  1905.      * subclassed by component developers.  Due to a restriction that
  1906.      * protected inner classes cannot be subclassed outside of a
  1907.      * package, this inner class has been made public.  When this
  1908.      * restriction is lifted for JDK1.1.7, this class will be made
  1909.      * protected.
  1910.      * The class used to obtain the accessible role for this object.
  1911.      * <p>
  1912.      * <strong>Warning:</strong>
  1913.      * Serialized objects of this class will not be compatible with
  1914.      * future Swing releases.  The current serialization support is appropriate
  1915.      * for short term storage or RMI between applications running the same
  1916.      * version of Swing.  A future release of Swing will provide support for
  1917.      * long term persistence.
  1918.      */
  1919.     public abstract class AccessibleJComponent extends AccessibleContext
  1920.         implements Serializable, AccessibleComponent {
  1921.  
  1922.     /**
  1923.      * Though the class is abstract, this should be called by
  1924.      * all sub-classes. 
  1925.      */
  1926.     protected AccessibleJComponent() {
  1927.         }
  1928.  
  1929.     protected ContainerListener accessibleContainerHandler = null;
  1930.  
  1931.     /**
  1932.      * Fire PropertyChange listener, if one is registered,
  1933.      * when children added/removed.
  1934.      */
  1935.     protected class AccessibleContainerHandler 
  1936.         implements ContainerListener {
  1937.         public void componentAdded(ContainerEvent e) {
  1938.         Component c = e.getChild();
  1939.         if (c != null && c instanceof Accessible) {
  1940.             AccessibleJComponent.this.firePropertyChange(
  1941.             AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, 
  1942.             null, ((Accessible) c).getAccessibleContext());
  1943.         }
  1944.         }
  1945.         public void componentRemoved(ContainerEvent e) {
  1946.         Component c = e.getChild();
  1947.         if (c != null && c instanceof Accessible) {
  1948.             AccessibleJComponent.this.firePropertyChange(
  1949.             AccessibleContext.ACCESSIBLE_CHILD_PROPERTY, 
  1950.             ((Accessible) c).getAccessibleContext(), null); 
  1951.         }
  1952.         }
  1953.     }
  1954.  
  1955.     /**
  1956.      * Add a PropertyChangeListener to the listener list.
  1957.      *
  1958.      * @param listener  The PropertyChangeListener to be added
  1959.      */
  1960.     public void addPropertyChangeListener(PropertyChangeListener listener) {
  1961.         if (accessibleContainerHandler == null) {
  1962.         accessibleContainerHandler = new AccessibleContainerHandler();
  1963.         JComponent.this.addContainerListener(accessibleContainerHandler);
  1964.         }
  1965.         super.addPropertyChangeListener(listener);
  1966.     }
  1967.  
  1968.     /**
  1969.      * Remove a PropertyChangeListener from the listener list.
  1970.      * This removes a PropertyChangeListener that was registered
  1971.      * for all properties.
  1972.      *
  1973.      * @param listener  The PropertyChangeListener to be removed
  1974.      */
  1975.     public void removePropertyChangeListener(PropertyChangeListener listener) {
  1976.         if (accessibleContainerHandler == null) {
  1977.         JComponent.this.removeContainerListener(accessibleContainerHandler);
  1978.         }
  1979.         super.removePropertyChangeListener(listener);
  1980.     }
  1981.  
  1982.  
  1983.     /**
  1984.          * Recursively search through the border hierarchy (if it exists)
  1985.      * for a TitledBorder with a non-null title.  This does a depth
  1986.          * first search on first the inside borders then the outside borders.
  1987.          * The assumption is that titles make really pretty inside borders
  1988.          * but not very pretty outside borders in compound border situations.
  1989.      * It's rather arbitrary, but hopefully decent UI programmers will
  1990.          * not create multiple titled borders for the same component.
  1991.      */
  1992.         protected String getBorderTitle(Border b) {
  1993.         String s;
  1994.         if (b instanceof TitledBorder) {
  1995.             return ((TitledBorder) b).getTitle();
  1996.         } else if (b instanceof CompoundBorder) {
  1997.             s = getBorderTitle(((CompoundBorder) b).getInsideBorder());
  1998.         if (s == null) {
  1999.             s = getBorderTitle(((CompoundBorder) b).getOutsideBorder());
  2000.         }
  2001.         return s;
  2002.         } else {
  2003.             return null;
  2004.         }
  2005.     }
  2006.             
  2007.         // AccessibleContext methods
  2008.         //
  2009.         /**
  2010.          * Get the accessible name of this object.  This should almost never
  2011.          * return java.awt.Component.getName(), as that generally isn't
  2012.          * a localized name, and doesn't have meaning for the user.  If the
  2013.          * object is fundamentally a text object (e.g. a menu item), the
  2014.          * accessible name should be the text of the object (e.g. "save").
  2015.          * If the object has a tooltip, the tooltip text may also be an
  2016.          * appropriate String to return.
  2017.          *
  2018.          * @return the localized name of the object -- can be null if this
  2019.          *         object does not have a name
  2020.          * @see AccessibleContext#setAccessibleName
  2021.          */
  2022.         public String getAccessibleName() {
  2023.         String name = accessibleName;
  2024.  
  2025.         // fallback to the titled border if it exists
  2026.         //
  2027.             if (name == null) {
  2028.         name = getBorderTitle(getBorder());
  2029.             }
  2030.  
  2031.         // fallback to the label labeling us if it exists
  2032.         //
  2033.             if (name == null) {
  2034.         Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
  2035.         if (o instanceof Accessible) {
  2036.             AccessibleContext ac = ((Accessible) o).getAccessibleContext();
  2037.             if (ac != null) {
  2038.             name = ac.getAccessibleName();
  2039.             }
  2040.         }
  2041.         }
  2042.         return name;
  2043.         }
  2044.  
  2045.         /**
  2046.          * Get the accessible description of this object.  This should be
  2047.          * a concise, localized description of what this object is - what
  2048.          * is it's meaning to the user.  If the object has a tooltip, the
  2049.          * tooltip text may be an appropriate string to return, assuming
  2050.          * it contains a concise description of the object (instead of just
  2051.          * the name of the object - e.g. a "Save" icon on a toolbar that
  2052.          * had "save" as the tooltip text shouldn't return the tooltip
  2053.          * text as the description, but something like "Saves the current
  2054.          * text document" instead).
  2055.          *
  2056.          * @return the localized description of the object -- can be null if
  2057.          * this object does not have a description
  2058.          * @see AccessibleContext#setAccessibleDescription
  2059.          */
  2060.         public String getAccessibleDescription() {
  2061.         String description = accessibleDescription;
  2062.  
  2063.         // fallback to the tool tip text if it exists
  2064.         //
  2065.             if (description == null) {
  2066.                 try {
  2067.                     description = getToolTipText(null);
  2068.                 } catch (Exception e) {
  2069.                     // Just in case the subclass overrode the
  2070.                     // getToolTipText method and actually
  2071.                     // requires a MouseEvent.
  2072.                     // [[[FIXME:  WDW - we probably should require this
  2073.                     // method to take a MouseEvent and just pass it on
  2074.                     // to getToolTipText.  The swing-feedback traffic
  2075.                     // leads me to believe getToolTipText might change,
  2076.                     // though, so I was hesitant to make this change at
  2077.                     // this time.]]]
  2078.                 }
  2079.             }
  2080.  
  2081.         // fallback to the label labeling us if it exists
  2082.         //
  2083.             if (description == null) {
  2084.         Object o = getClientProperty(JLabel.LABELED_BY_PROPERTY);
  2085.         if (o instanceof Accessible) {
  2086.             AccessibleContext ac = ((Accessible) o).getAccessibleContext();
  2087.             if (ac != null) {
  2088.             description = ac.getAccessibleDescription();
  2089.             }
  2090.         }
  2091.         }
  2092.  
  2093.         return description;
  2094.         }
  2095.  
  2096.         /**
  2097.          * Get the role of this object.
  2098.          *
  2099.          * @return an instance of AccessibleRole describing the role of the
  2100.          * object
  2101.          * @see AccessibleRole
  2102.          */
  2103.         public AccessibleRole getAccessibleRole() {
  2104.             return AccessibleRole.SWING_COMPONENT;
  2105.         }
  2106.  
  2107.         /**
  2108.          * Get the state of this object.
  2109.          *
  2110.          * @return an instance of AccessibleStateSet containing the current
  2111.          * state set of the object
  2112.          * @see AccessibleState
  2113.          */
  2114.         public AccessibleStateSet getAccessibleStateSet() {
  2115.             return SwingUtilities.getAccessibleStateSet(JComponent.this);
  2116.         }
  2117.  
  2118.         /**
  2119.          * Get the Accessible parent of this object.  If the parent of this
  2120.          * object implements Accessible, this method should simply return
  2121.          * getParent().
  2122.          *
  2123.          * @return the Accessible parent of this object -- can be null if this
  2124.          * object does not have an Accessible parent
  2125.          */
  2126.         public Accessible getAccessibleParent() {
  2127.             if (accessibleParent != null) {
  2128.                 return accessibleParent;
  2129.             } else {
  2130.                 Container parent = getParent();
  2131.                 if (parent instanceof Accessible) {
  2132.                     return (Accessible) parent;
  2133.                 }
  2134.             }
  2135.             return null;
  2136.         }
  2137.  
  2138.         /**
  2139.          * Get the index of this object in its accessible parent.
  2140.          *
  2141.          * @return the index of this object in its parent; -1 if this
  2142.          * object does not have an accessible parent.
  2143.          * @see #getAccessibleParent
  2144.          */
  2145.         public int getAccessibleIndexInParent() {
  2146.             return SwingUtilities.getAccessibleIndexInParent(JComponent.this);
  2147.         }
  2148.  
  2149.         /**
  2150.          * Returns the number of accessible children in the object.  If all
  2151.          * of the children of this object implement Accessible, than this
  2152.          * method should return the number of children of this object.
  2153.          *
  2154.          * @return the number of accessible children in the object.
  2155.          */
  2156.         public int getAccessibleChildrenCount() {
  2157.         // Always delegate to the UI if it exists
  2158.         if (ui != null) {
  2159.                 return ui.getAccessibleChildrenCount(JComponent.this);
  2160.         } else {
  2161.             return SwingUtilities.getAccessibleChildrenCount(JComponent.this);
  2162.         }
  2163.         }
  2164.  
  2165.         /**
  2166.          * Return the nth Accessible child of the object.
  2167.          *
  2168.          * @param i zero-based index of child
  2169.          * @return the nth Accessible child of the object
  2170.          */
  2171.         public Accessible getAccessibleChild(int i) {
  2172.         // Always delegate to the UI if it exists
  2173.         if (ui != null) {
  2174.                 return ui.getAccessibleChild(JComponent.this, i);
  2175.         } else {
  2176.             return SwingUtilities.getAccessibleChild(JComponent.this, i);
  2177.             }
  2178.         }
  2179.  
  2180.         /**
  2181.          * Return the locale of this object.
  2182.          *
  2183.          * @return the locale of this object
  2184.          */
  2185.         public Locale getLocale() {
  2186.             return JComponent.this.getLocale();
  2187.         }
  2188.  
  2189.         /**
  2190.          * Get the AccessibleComponent associated with this object if one
  2191.          * exists.  Otherwise return null.
  2192.      *
  2193.      * @return the component
  2194.          */
  2195.         public AccessibleComponent getAccessibleComponent() {
  2196.             return this;
  2197.         }
  2198.  
  2199.  
  2200.         // AccessibleComponent methods
  2201.         //
  2202.         /**
  2203.          * Get the background color of this object.
  2204.          *
  2205.          * @return the background color, if supported, of the object;
  2206.          * otherwise, null
  2207.          */
  2208.         public Color getBackground() {
  2209.             return JComponent.this.getBackground();
  2210.         }
  2211.  
  2212.         // NOTE: IN THE NEXT MAJOR RELEASE, isOpaque WILL MIGRATE
  2213.         //       TO java.awt.Component -- ADJUST @SEE LINK BELOW.
  2214.         /**
  2215.          * Set the background color of this object.
  2216.          * (For transparency, see <code>isOpaque</code>.)
  2217.          *
  2218.          * @param c the new Color for the background
  2219.          * @see JComponent#isOpaque
  2220.          */
  2221.         public void setBackground(Color c) {
  2222.             JComponent.this.setBackground(c);
  2223.         }
  2224.  
  2225.         /**
  2226.          * Get the foreground color of this object.
  2227.          *
  2228.          * @return the foreground color, if supported, of the object;
  2229.          * otherwise, null
  2230.          */
  2231.         public Color getForeground() {
  2232.             return JComponent.this.getForeground();
  2233.         }
  2234.  
  2235.         /**
  2236.          * Set the foreground color of this object.
  2237.          *
  2238.          * @param c the new Color for the foreground
  2239.          */
  2240.         public void setForeground(Color c) {
  2241.             JComponent.this.setForeground(c);
  2242.         }
  2243.  
  2244.         /**
  2245.          * Get the Cursor of this object.
  2246.          *
  2247.          * @return the Cursor, if supported, of the object; otherwise, null
  2248.          */
  2249.         public Cursor getCursor() {
  2250.             return JComponent.this.getCursor();
  2251.         }
  2252.  
  2253.         /**
  2254.          * Set the Cursor of this object.
  2255.          *
  2256.          * @param c the new Cursor for the object
  2257.          */
  2258.         public void setCursor(Cursor cursor) {
  2259.             JComponent.this.setCursor(cursor);
  2260.         }
  2261.  
  2262.         /**
  2263.          * Get the Font of this object.
  2264.          *
  2265.          * @return the Font,if supported, for the object; otherwise, null
  2266.          */
  2267.         public Font getFont() {
  2268.             return JComponent.this.getFont();
  2269.         }
  2270.  
  2271.         /**
  2272.          * Set the Font of this object.
  2273.          *
  2274.          * @param f the new Font for the object
  2275.          */
  2276.         public void setFont(Font f) {
  2277.             JComponent.this.setFont(f);
  2278.         }
  2279.  
  2280.         /**
  2281.          * Get the FontMetrics of this object.
  2282.          *
  2283.          * @param f the Font
  2284.          * @return the FontMetrics, if supported, the object; otherwise, null
  2285.          * @see #getFont
  2286.          */
  2287.         public FontMetrics getFontMetrics(Font f) {
  2288.             return JComponent.this.getFontMetrics(f);
  2289.         }
  2290.  
  2291.         /**
  2292.          * Determine if the object is enabled.
  2293.          *
  2294.          * @return true if object is enabled; otherwise, false
  2295.          */
  2296.         public boolean isEnabled() {
  2297.             return JComponent.this.isEnabled();
  2298.         }
  2299.  
  2300.         /**
  2301.          * Set the enabled state of the object.
  2302.          *
  2303.          * @param b if true, enables this object; otherwise, disables it
  2304.          */
  2305.         public void setEnabled(boolean b) {
  2306.             boolean old = JComponent.this.isEnabled();
  2307.             JComponent.this.setEnabled(b);
  2308.             if (b != old) {
  2309.                 if (accessibleContext != null) {
  2310.                     if (b) {
  2311.                         accessibleContext.firePropertyChange(
  2312.                                 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  2313.                                 null, AccessibleState.ENABLED);
  2314.                     } else {
  2315.                         accessibleContext.firePropertyChange(
  2316.                                 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  2317.                                 AccessibleState.ENABLED, null);
  2318.                     }
  2319.                 }
  2320.             }
  2321.         }
  2322.  
  2323.         /**
  2324.          * Determine if the object is visible.  Note: this means that the
  2325.          * object intends to be visible; however, it may not in fact be
  2326.          * showing on the screen because one of the objects that this object
  2327.          * is contained by is not visible.  To determine if an object is
  2328.          * showing on the screen, use isShowing().
  2329.          *
  2330.          * @return true if object is visible; otherwise, false
  2331.          */
  2332.         public boolean isVisible() {
  2333.             return JComponent.this.isVisible();
  2334.         }
  2335.  
  2336.         /**
  2337.          * Set the visible state of the object.
  2338.          *
  2339.          * @param b if true, shows this object; otherwise, hides it
  2340.          */
  2341.         public void setVisible(boolean b) {
  2342.             boolean old = JComponent.this.isVisible();
  2343.             JComponent.this.setVisible(b);
  2344.             if (b != old) {
  2345.                 if (accessibleContext != null) {
  2346.                     if (b) {
  2347.                         accessibleContext.firePropertyChange(
  2348.                                 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  2349.                                 null, AccessibleState.VISIBLE);
  2350.                     } else {
  2351.                         accessibleContext.firePropertyChange(
  2352.                                 AccessibleContext.ACCESSIBLE_STATE_PROPERTY,
  2353.                                 AccessibleState.VISIBLE, null);
  2354.                     }
  2355.                 }
  2356.             }
  2357.         }
  2358.  
  2359.         /**
  2360.          * Determine if the object is showing.  This is determined by checking
  2361.          * the visibility of the object and ancestors of the object.  Note:
  2362.          * this will return true even if the object is obscured by another
  2363.          * (for example, it happens to be underneath a menu that was pulled
  2364.          * down).
  2365.          *
  2366.          * @return true if object is showing; otherwise, false
  2367.          */
  2368.         public boolean isShowing() {
  2369.             return JComponent.this.isShowing();
  2370.         }
  2371.  
  2372.         /**
  2373.          * Checks whether the specified point is within this object's bounds,
  2374.          * where the point's x and y coordinates are defined to be relative to
  2375.          * the coordinate system of the object.
  2376.          *
  2377.          * @param p the Point relative to the coordinate system of the object
  2378.          * @return true if object contains Point; otherwise false
  2379.          */
  2380.         public boolean contains(Point p) {
  2381.             return JComponent.this.contains(p);
  2382.         }
  2383.  
  2384.         /**
  2385.          * Returns the location of the object on the screen.
  2386.          *
  2387.          * @return location of object on screen -- can be null if this object
  2388.          * is not on the screen
  2389.          */
  2390.         public Point getLocationOnScreen() {
  2391.             if (JComponent.this.isShowing()) {
  2392.                 return JComponent.this.getLocationOnScreen();
  2393.             } else {
  2394.                 return null;
  2395.             }
  2396.         }
  2397.  
  2398.         /**
  2399.          * Gets the location of the object relative to the parent in the form
  2400.          * of a point specifying the object's top-left corner in the screen's
  2401.          * coordinate space.
  2402.          *
  2403.          * @return An instance of Point representing the top-left corner of
  2404.          * the objects's bounds in the coordinate space of the screen; null if
  2405.          * this object or its parent are not on the screen
  2406.          */
  2407.         public Point getLocation() {
  2408.             return JComponent.this.getLocation();
  2409.         }
  2410.  
  2411.         /**
  2412.          * Sets the location of the object relative to the parent.
  2413.          */
  2414.         public void setLocation(Point p) {
  2415.             JComponent.this.setLocation(p);
  2416.         }
  2417.  
  2418.         /**
  2419.          * Gets the bounds of this object in the form of a Rectangle object.
  2420.          * The bounds specify this object's width, height, and location
  2421.          * relative to its parent.
  2422.          *
  2423.          * @return A rectangle indicating this component's bounds; null if
  2424.          * this object is not on the screen.
  2425.          */
  2426.         public Rectangle getBounds() {
  2427.             return JComponent.this.getBounds();
  2428.         }
  2429.  
  2430.         /**
  2431.          * Sets the bounds of this object in the form of a Rectangle object.
  2432.          * The bounds specify this object's width, height, and location
  2433.          * relative to its parent.
  2434.          *
  2435.          * @param A rectangle indicating this component's bounds
  2436.          */
  2437.         public void setBounds(Rectangle r) {
  2438.             JComponent.this.setBounds(r);
  2439.         }
  2440.  
  2441.         /**
  2442.          * Returns the size of this object in the form of a Dimension object.
  2443.          * The height field of the Dimension object contains this objects's
  2444.          * height, and the width field of the Dimension object contains this
  2445.          * object's width.
  2446.          *
  2447.          * @return A Dimension object that indicates the size of this
  2448.          *         component; null if this object is not on the screen
  2449.          */
  2450.         public Dimension getSize() {
  2451.             return JComponent.this.getSize();
  2452.         }
  2453.  
  2454.         /**
  2455.          * Resizes this object so that it has width width and height.
  2456.          *
  2457.          * @param d - The dimension specifying the new size of the object.
  2458.          */
  2459.         public void setSize(Dimension d) {
  2460.             JComponent.this.setSize(d);
  2461.         }
  2462.  
  2463.         /**
  2464.          * Returns the Accessible child, if one exists, contained at the local
  2465.          * coordinate Point.
  2466.          *
  2467.          * @param p The point defining the top-left corner of the Accessible,
  2468.          * given in the coordinate space of the object's parent.
  2469.          * @return the Accessible, if it exists, at the specified location;
  2470.          * else null
  2471.          */
  2472.         public Accessible getAccessibleAt(Point p) {
  2473.             return SwingUtilities.getAccessibleAt(JComponent.this, p);
  2474.         }
  2475.  
  2476.         /**
  2477.          * Returns whether this object can accept focus or not.
  2478.          *
  2479.          * @return true if object can accept focus; otherwise false
  2480.          */
  2481.         public boolean isFocusTraversable() {
  2482.             return JComponent.this.isFocusTraversable();
  2483.         }
  2484.  
  2485.         /**
  2486.          * Requests focus for this object.
  2487.          */
  2488.         public void requestFocus() {
  2489.             JComponent.this.requestFocus();
  2490.         }
  2491.  
  2492.         /**
  2493.          * Adds the specified focus listener to receive focus events from this
  2494.          * component.
  2495.          *
  2496.          * @param l the focus listener
  2497.          */
  2498.         public void addFocusListener(FocusListener l) {
  2499.             JComponent.this.addFocusListener(l);
  2500.         }
  2501.  
  2502.         /**
  2503.          * Removes the specified focus listener so it no longer receives focus
  2504.          * events from this component.
  2505.          *
  2506.          * @param l the focus listener
  2507.          */
  2508.         public void removeFocusListener(FocusListener l) {
  2509.             JComponent.this.removeFocusListener(l);
  2510.         }
  2511.  
  2512.     } // inner class AccessibleJComponent
  2513.  
  2514.  
  2515.     
  2516.     /**
  2517.      * @return a small Hashtable
  2518.      * @see #putClientProperty
  2519.      * @see #getClientProperty
  2520.      */
  2521.     private Dictionary getClientProperties() {
  2522.         if (clientProperties == null) {
  2523.             clientProperties = new Hashtable(2);
  2524.         }
  2525.         return clientProperties;
  2526.     }
  2527.  
  2528.  
  2529.     /**
  2530.      * Returns the value of the property with the specified key.  Only
  2531.      * properties added with <code>putClientProperty</code> will return
  2532.      * a non-null value.  
  2533.      * 
  2534.      * @return the value of this property or null
  2535.      * @see #putClientProperty
  2536.      */
  2537.     public final Object getClientProperty(Object key) {
  2538.          if(clientProperties == null) {
  2539.          return null;
  2540.      }
  2541.      else {
  2542.          return getClientProperties().get(key);
  2543.     }
  2544.     }
  2545.  
  2546.  
  2547.     /**
  2548.      * Add an arbitrary key/value "client property" to this component.
  2549.      * <p>
  2550.      * The <code>get/putClientProperty<code> methods provide access to 
  2551.      * a small per-instance hashtable. Callers can use get/putClientProperty
  2552.      * to annotate components that were created by another module, e.g. a 
  2553.      * layout manager might store per child constraints this way.  For example:
  2554.      * <pre>
  2555.      * componentA.putClientProperty("to the left of", componentB);
  2556.      * </pre>
  2557.      * <p>
  2558.      * If value is null this method will remove the property.
  2559.      * Changes to client properties are reported with PropertyChange
  2560.      * events.  The name of the property (for the sake of PropertyChange
  2561.      * events) is <code>key.toString()</code>.  
  2562.      * <p>
  2563.      * The clientProperty dictionary is not intended to support large 
  2564.      * scale extensions to JComponent nor should be it considered an 
  2565.      * alternative to subclassing when designing a new component.
  2566.      * 
  2567.      * @see #getClientProperty
  2568.      * @see #addPropertyChangeListener
  2569.      */
  2570.     public final void putClientProperty(Object key, Object value) {
  2571.         Object oldValue = getClientProperties().get(key);
  2572.  
  2573.         if (value != null) {
  2574.             getClientProperties().put(key, value);
  2575.         } else {
  2576.             getClientProperties().remove(key);
  2577.         }
  2578.  
  2579.         firePropertyChange(key.toString(), oldValue, value);
  2580.     }
  2581.  
  2582.  
  2583.     /* --- Transitional java.awt.Component Support ---
  2584.      *
  2585.      * The methods and fields in this section will migrate to
  2586.      * java.awt.Component in the next JDK release.
  2587.      *
  2588.      */
  2589.  
  2590.     private SwingPropertyChangeSupport changeSupport;
  2591.  
  2592.  
  2593.     /**
  2594.      * Returns true if this component is a lightweight, i.e. if it doesn't
  2595.      * have a native window system peer.
  2596.      * <p>
  2597.      * This method will migrate to java.awt.Component in the next major JDK release
  2598.      *
  2599.      * @return true if this component is a lightweight
  2600.      */
  2601.     public static boolean isLightweightComponent(Component c) {
  2602.         return c.getPeer() instanceof java.awt.peer.LightweightPeer;
  2603.     }
  2604.  
  2605.  
  2606.     /**
  2607.      * Moves and resizes this component.
  2608.      *
  2609.      * @see java.awt.Component#setBounds
  2610.      */
  2611.     public void reshape(int x, int y, int w, int h) {
  2612.         if(isShowing()) {
  2613.             /* If there is an intersection between the new bounds and the old
  2614.              * one, refresh only the visible rects
  2615.              */
  2616.             if(!((_bounds.x + _bounds.width <= x) ||
  2617.                  (_bounds.y + _bounds.height <= y) ||
  2618.                  (_bounds.x >= (x + w)) ||
  2619.                  (_bounds.y >= (y + h)))) {
  2620.                 Rectangle[] rev = SwingUtilities.computeDifference(getBounds(),
  2621.                                                                    new Rectangle(x,y,w,h));
  2622.                 int i,c;
  2623.                 Container parent = getParent();
  2624.                 for(i=0,c=rev.length ; i < c ; i++) {
  2625.                     parent.repaint(rev[i].x,rev[i].y,rev[i].width,rev[i].height);
  2626.                     // System.out.println("Repaint " + rev[i]);
  2627.                 }
  2628.             } else {
  2629.                 getParent().repaint(_bounds.x,_bounds.y,_bounds.width,_bounds.height);
  2630.             }
  2631.         }
  2632.         _bounds.setBounds(x, y, w, h);
  2633.         super.reshape(x, y, w, h);
  2634.     }
  2635.  
  2636.  
  2637.     /**
  2638.      * Store the bounds of this component into "return value" <b>rv</b> and
  2639.      * return <b>rv</b>.  If rv is null a new Rectangle is allocated.
  2640.      * This version of getBounds() is useful if the caller
  2641.      * wants to avoid allocating a new Rectangle object on the heap.
  2642.      *
  2643.      * @param rv the return value, modified to the components bounds
  2644.      * @return rv
  2645.      */
  2646.     public Rectangle getBounds(Rectangle rv) {
  2647.         if (rv == null) {
  2648.             return new Rectangle(getX(), getY(), getWidth(), getHeight());
  2649.         }
  2650.         else {
  2651.             rv.setBounds(getX(), getY(), getWidth(), getHeight());
  2652.             return rv;
  2653.         }
  2654.     }
  2655.  
  2656.  
  2657.     /**
  2658.      * Store the width/height of this component into "return value" <b>rv</b>
  2659.      * and return <b>rv</b>.   If rv is null a new Dimension object is
  2660.      * allocated.  This version of getSize() is useful if the
  2661.      * caller wants to avoid allocating a new Dimension object on the heap.
  2662.      *
  2663.      * @param rv the return value, modified to the components size
  2664.      * @return rv
  2665.      */
  2666.     public Dimension getSize(Dimension rv) {
  2667.         if (rv == null) {
  2668.             return new Dimension(getWidth(), getHeight());
  2669.         }
  2670.         else {
  2671.             rv.setSize(getWidth(), getHeight());
  2672.             return rv;
  2673.         }
  2674.     }
  2675.  
  2676.  
  2677.     /**
  2678.      * Store the x,y origin of this component into "return value" <b>rv</b>
  2679.      * and return <b>rv</b>.   If rv is null a new Point is allocated.
  2680.      * This version of getLocation() is useful if the
  2681.      * caller wants to avoid allocating a new Point object on the heap.
  2682.      *
  2683.      * @param rv the return value, modified to the components location
  2684.      * @return rv
  2685.      */
  2686.     public Point getLocation(Point rv) {
  2687.         if (rv == null) {
  2688.             return new Point(getX(), getY());
  2689.         }
  2690.         else {
  2691.             rv.setLocation(getX(), getY());
  2692.             return rv;
  2693.         }
  2694.     }
  2695.  
  2696.  
  2697.     /**
  2698.      * Return the current x coordinate of the components origin.
  2699.      * This method is preferable to writing component.getBounds().x,
  2700.      * or component.getLocation().x because it doesn't cause any
  2701.      * heap allocations.
  2702.      * <p>
  2703.      * This method will migrate to java.awt.Component in the next major JDK release
  2704.      *
  2705.      * @return the current x coordinate of the components origin.
  2706.      */
  2707.     public int getX() { return _bounds.x; }
  2708.  
  2709.  
  2710.     /**
  2711.      * Return the current y coordinate of the components origin.
  2712.      * This method is preferable to writing component.getBounds().y,
  2713.      * or component.getLocation().y because it doesn't cause any
  2714.      * heap allocations.
  2715.      * <p>
  2716.      * This method will migrate to java.awt.Component in the next major JDK release
  2717.      *
  2718.      * @return the current y coordinate of the components origin.
  2719.      */
  2720.     public int getY() { return _bounds.y; }
  2721.  
  2722.  
  2723.     /**
  2724.      * Return the current width of this component.
  2725.      * This method is preferable to writing component.getBounds().width,
  2726.      * or component.getSize().width because it doesn't cause any
  2727.      * heap allocations.
  2728.      * <p>
  2729.      * This method will migrate to java.awt.Component in the next major JDK release
  2730.      *
  2731.      * @return the current width of this component.
  2732.      */
  2733.     public int getWidth() { return _bounds.width; }
  2734.  
  2735.  
  2736.     /**
  2737.      * Return the current height of this component.
  2738.      * This method is preferable to writing component.getBounds().height,
  2739.      * or component.getSize().height because it doesn't cause any
  2740.      * heap allocations.
  2741.      * <p>
  2742.      * This method will migrate to java.awt.Component in the next major JDK release
  2743.      *
  2744.      * @return the current height of this component.
  2745.      */
  2746.     public int getHeight() { return _bounds.height; }
  2747.  
  2748.  
  2749.     /**
  2750.      * Returns true if this Component has the keyboard focus.
  2751.      * <p>
  2752.      * This method will migrate to java.awt.Component in the next major JDK release
  2753.      *
  2754.      * @return true if this Component has the keyboard focus.
  2755.      */
  2756.     public boolean hasFocus() {
  2757.         return getFlag(HAS_FOCUS);
  2758.     }
  2759.  
  2760.  
  2761.     /**
  2762.      * Returns true if this component is completely opaque.
  2763.      * <p>
  2764.      * An opaque component paints every pixel within its
  2765.      * rectangular region. A non-opaque component paints only some of
  2766.      * its pixels, allowing the pixels underneath it to "show through".
  2767.      * A component that does not fully paint its pixels therefore
  2768.      * provides a degree of transparency.
  2769.      * <p>
  2770.      * Subclasses that guarantee to always completely paint their contents should
  2771.      * override this method and return true.
  2772.      * <p>
  2773.      * This method will migrate to java.awt.Component in the next major JDK release
  2774.      *
  2775.      * @return true if this component is completely opaque.
  2776.      * @see #setOpaque
  2777.      */
  2778.     public boolean isOpaque() {
  2779.         return getFlag(IS_OPAQUE);
  2780.     }
  2781.  
  2782.  
  2783.     /**
  2784.      * If true the components background will be filled with the
  2785.      * background color. Otherwise, the background is transparent,
  2786.      * and whatever is underneath will show through.
  2787.      * <p>
  2788.      * The default value of this property is false.
  2789.      * <p>
  2790.      * This is a JavaBeans bound property.
  2791.      *
  2792.      * @see #isOpaque
  2793.      */
  2794.     public void setOpaque(boolean isOpaque) {
  2795.         boolean oldValue = getFlag(IS_OPAQUE);
  2796.         setFlag(IS_OPAQUE, isOpaque);
  2797.         firePropertyChange("opaque", oldValue, isOpaque);
  2798.     }
  2799.  
  2800.  
  2801.     /**
  2802.      * If the specified retangle is completely obscured by any of this
  2803.      * components opaque children then return true.  Only direct children
  2804.      * are considered, more distant descendants are ignored.  A JComponent
  2805.      * is opaque if JComponent.isOpaque() returns true, other lightweight
  2806.      * components are always considered transparent, and heavyweight components
  2807.      * are always considered opaque.
  2808.      *
  2809.      * @return true if the specified rectangle is obscured by an opaque child
  2810.      */
  2811.     boolean rectangleIsObscured(int x,int y,int width,int height)
  2812.     {
  2813.         int numChildren = getComponentCount();
  2814.  
  2815.         for(int i = 0; i < numChildren; i++) {
  2816.             Component child = getComponent(i);
  2817.             Rectangle childBounds;
  2818.  
  2819.             if (child instanceof JComponent) {
  2820.                 childBounds = ((JComponent)child)._bounds;
  2821.             } else {
  2822.                 childBounds = child.getBounds();
  2823.             }
  2824.  
  2825.             if (x >= childBounds.x && (x + width) <= (childBounds.x + childBounds.width) &&
  2826.                 y >= childBounds.y && (y + height) <= (childBounds.y + childBounds.height)) {
  2827.  
  2828.                 if(child instanceof JComponent) {
  2829. //            System.out.println("A) checking opaque: " + ((JComponent)child).isOpaque() + "  " + child);
  2830. //            System.out.print("B) ");
  2831. //            Thread.dumpStack();
  2832.                     return ((JComponent)child).isOpaque();
  2833.                 } else {
  2834.                     /** Sometimes a heavy weight can have a bound larger than it's peer size
  2835.                      *  so we should always draw under heavy weights
  2836.                      */
  2837.                     return false;
  2838.                 }
  2839.             }
  2840.         }
  2841.  
  2842.         return false;
  2843.     }
  2844.  
  2845.  
  2846.     /**
  2847.      * Returns the Component's "visible rect rectangle" -  the
  2848.      * intersection of the visible rectangles for this component
  2849.      * and all of its ancestors.  The return value is stored in
  2850.      * <code>visibleRect</code>
  2851.      *
  2852.      * @see #getVisibleRect
  2853.      */
  2854.     static final void computeVisibleRect(Component c, Rectangle visibleRect) {
  2855.         Container p = c.getParent();
  2856.         Rectangle bounds = c.getBounds();
  2857.  
  2858.         if (p == null || p instanceof Window || p instanceof Applet) {
  2859.             visibleRect.setBounds(0, 0, bounds.width, bounds.height);
  2860.         } else {
  2861.             computeVisibleRect(p, visibleRect);
  2862.             visibleRect.x -= bounds.x;
  2863.             visibleRect.y -= bounds.y;
  2864.             SwingUtilities.computeIntersection(0,0,bounds.width,bounds.height,visibleRect);
  2865.         }
  2866.     }
  2867.  
  2868.  
  2869.     /**
  2870.      * Returns the Component's "visible rect rectangle" -  the
  2871.      * intersection of the visible rectangles for this component
  2872.      * and all of its ancestors.  The return value is stored in
  2873.      * <code>visibleRect</code>
  2874.      *
  2875.      * @see #getVisibleRect
  2876.      */
  2877.     public void computeVisibleRect(Rectangle visibleRect) {
  2878.         computeVisibleRect(this, visibleRect);
  2879.     }
  2880.  
  2881.  
  2882.     /**
  2883.      * Returns the Component's "visible rectangle" -  the
  2884.      * intersection of this components visible rectangle:
  2885.      * <pre>
  2886.      * new Rectangle(0, 0, getWidth(), getHeight());
  2887.      * </pre>
  2888.      * and all of its ancestors visible Rectangles.
  2889.      *
  2890.      * @return the visible rectangle
  2891.      */
  2892.     public Rectangle getVisibleRect() {
  2893.         Rectangle visibleRect = new Rectangle();
  2894.  
  2895.         computeVisibleRect(visibleRect);
  2896.         return visibleRect;
  2897.     }
  2898.  
  2899.  
  2900.     /**
  2901.      * Support for reporting bound property changes.  If oldValue and
  2902.      * newValue are not equal and the PropertyChangeEvent listener list
  2903.      * isn't empty, then fire a PropertyChange event to each listener.
  2904.      * This method has an overloaded method for each primitive type.  For
  2905.      * example, here's how to write a bound property set method whose
  2906.      * value is an int:
  2907.      * <pre>
  2908.      * public void setFoo(int newValue) {
  2909.      *     int oldValue = foo;
  2910.      *     foo = newValue;
  2911.      *     firePropertyChange("foo", oldValue, newValue);
  2912.      * }
  2913.      * </pre>
  2914.      * <p>
  2915.      * This method will migrate to java.awt.Component in the next major JDK release
  2916.      *
  2917.      * @param propertyName  The programmatic name of the property that was changed.
  2918.      * @param oldValue  The old value of the property.
  2919.      * @param newValue  The new value of the property.
  2920.      * @see java.beans.PropertyChangeSupport
  2921.      */
  2922.     protected void firePropertyChange(String propertyName, Object oldValue, Object newValue) {
  2923.         if (changeSupport != null) {
  2924.             changeSupport.firePropertyChange(propertyName, oldValue, newValue);
  2925.         }
  2926.     }
  2927.  
  2928.     /*
  2929.      * PENDING(hmuller) in JDK1.2 the following firePropertyChange overloads
  2930.      * should additional check for a non-empty listener list with
  2931.      * changeSupport.hasListeners(propertyName) before calling firePropertyChange.
  2932.      */
  2933.  
  2934.     /**
  2935.      * Reports a bound property change.
  2936.      * @see #firePropertyChange(java.lang.String, java.lang.Object, java.lang.Object)
  2937.      */
  2938.     public void firePropertyChange(String propertyName, byte oldValue, byte newValue) {
  2939.         if ((changeSupport != null) && (oldValue != newValue)) {
  2940.             changeSupport.firePropertyChange(propertyName, new Byte(oldValue), new Byte(newValue));
  2941.         }
  2942.     }
  2943.  
  2944.     /**
  2945.      * Reports a bound property change.
  2946.      * @see #firePropertyChange(java.lang.String, java.lang.Object, java.lang.Object)
  2947.      */
  2948.      public void firePropertyChange(String propertyName, char oldValue, char newValue) {
  2949.          if ((changeSupport != null) && (oldValue != newValue)) {
  2950.              changeSupport.firePropertyChange(propertyName, new Character(oldValue), new Character(newValue));
  2951.          }
  2952.     }
  2953.  
  2954.     /**
  2955.      * Reports a bound property change.
  2956.      * @see #firePropertyChange(java.lang.String, java.lang.Object, java.lang.Object)
  2957.      */
  2958.     public void firePropertyChange(String propertyName, short oldValue, short newValue) {
  2959.         if ((changeSupport != null) && (oldValue != newValue)) {
  2960.             changeSupport.firePropertyChange(propertyName, new Short(oldValue), new Short(newValue));
  2961.         }
  2962.     }
  2963.  
  2964.     /**
  2965.      * Reports a bound property change.
  2966.      * @see #firePropertyChange(java.lang.String, java.lang.Object, java.lang.Object)
  2967.      */
  2968.     public void firePropertyChange(String propertyName, int oldValue, int newValue) {
  2969.         if ((changeSupport != null) && (oldValue != newValue)) {
  2970.             changeSupport.firePropertyChange(propertyName, new Integer(oldValue), new Integer(newValue));
  2971.         }
  2972.     }
  2973.  
  2974.     /**
  2975.      * Reports a bound property change.
  2976.      * @see #firePropertyChange(java.lang.String, java.lang.Object, java.lang.Object)
  2977.      */
  2978.     public void firePropertyChange(String propertyName, long oldValue, long newValue) {
  2979.         if ((changeSupport != null) && (oldValue != newValue)) {
  2980.             changeSupport.firePropertyChange(propertyName, new Long(oldValue), new Long(newValue));
  2981.         }
  2982.     }
  2983.  
  2984.     /**
  2985.      * Reports a bound property change.
  2986.      * @see #firePropertyChange(java.lang.String, java.lang.Object, java.lang.Object)
  2987.      */
  2988.     public void firePropertyChange(String propertyName, float oldValue, float newValue) {
  2989.         if ((changeSupport != null) && (oldValue != newValue)) {
  2990.             changeSupport.firePropertyChange(propertyName, new Float(oldValue), new Float(newValue));
  2991.         }
  2992.     }
  2993.  
  2994.     /**
  2995.      * Reports a bound property change.
  2996.      * @see #firePropertyChange(java.lang.String, java.lang.Object, java.lang.Object)
  2997.      */
  2998.     public void firePropertyChange(String propertyName, double oldValue, double newValue) {
  2999.         if ((changeSupport != null) && (oldValue != newValue)) {
  3000.             changeSupport.firePropertyChange(propertyName, new Double(oldValue), new Double(newValue));
  3001.         }
  3002.     }
  3003.  
  3004.     /**
  3005.      * Reports a bound property change.
  3006.      * @see #firePropertyChange(java.lang.String, java.lang.Object, java.lang.Object)
  3007.      */
  3008.     public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) {
  3009.         if ((changeSupport != null) && (oldValue != newValue)) {
  3010.             changeSupport.firePropertyChange(propertyName, new Boolean(oldValue), new Boolean(newValue));
  3011.         }
  3012.     }
  3013.  
  3014.  
  3015.     /**
  3016.      * Add a PropertyChangeListener to the listener list.
  3017.      * The listener is registered for all properties.
  3018.      * <p>
  3019.      * A PropertyChangeEvent will get fired in response to setting
  3020.      * a bound property, e.g. setFont, setBackground, or setForeground.
  3021.      * Note that if the current component is inheriting its foreground,
  3022.      * background, or font from its container, then no event will be
  3023.      * fired in response to a change in the inherited property.
  3024.      * <p>
  3025.      * This method will migrate to java.awt.Component in the next major JDK release
  3026.      *
  3027.      * @param listener  The PropertyChangeListener to be added
  3028.      */
  3029.     public synchronized void addPropertyChangeListener(PropertyChangeListener listener) {
  3030.         if (changeSupport == null) {
  3031.             changeSupport = new SwingPropertyChangeSupport(this);
  3032.         }
  3033.         changeSupport.addPropertyChangeListener(listener);
  3034.     }
  3035.  
  3036.  
  3037.     /**
  3038.      * Remove a PropertyChangeListener from the listener list.
  3039.      * This removes a PropertyChangeListener that was registered
  3040.      * for all properties.
  3041.      * <p>
  3042.      * This method will migrate to java.awt.Component in the next major JDK release
  3043.      *
  3044.      * @param listener  The PropertyChangeListener to be removed
  3045.      */
  3046.     public synchronized void removePropertyChangeListener(PropertyChangeListener listener) {
  3047.         if (changeSupport != null) {
  3048.             changeSupport.removePropertyChangeListener(listener);
  3049.         }
  3050.     }
  3051.  
  3052.  
  3053.     /**
  3054.      * Support for reporting constrained property changes.  This method can be called
  3055.      * when a constrained property has changed and it will send the appropriate
  3056.      * PropertyChangeEvent to any registered VetoableChangeListeners.
  3057.      * <p>
  3058.      * This method will migrate to java.awt.Component in the next major JDK release
  3059.      *
  3060.      * @exception PropertyVetoException when the attempt to set the property is vetoed
  3061.      *            by the receiver.
  3062.      */
  3063.     protected void fireVetoableChange(String propertyName, Object oldValue, Object newValue)
  3064.         throws java.beans.PropertyVetoException
  3065.     {
  3066.         if (vetoableChangeSupport == null) {
  3067.             return;
  3068.         }
  3069.         vetoableChangeSupport.fireVetoableChange(propertyName, oldValue, newValue);
  3070.     }
  3071.  
  3072.  
  3073.     /**
  3074.      * Add a VetoableChangeListener to the listener list.
  3075.      * The listener is registered for all properties.
  3076.      * <p>
  3077.      * This method will migrate to java.awt.Component in the next major JDK release
  3078.      *
  3079.      * @param listener  The VetoableChangeListener to be added
  3080.      */
  3081.     public synchronized void addVetoableChangeListener(VetoableChangeListener listener) {
  3082.         if (vetoableChangeSupport == null) {
  3083.             vetoableChangeSupport = new java.beans.VetoableChangeSupport(this);
  3084.         }
  3085.         vetoableChangeSupport.addVetoableChangeListener(listener);
  3086.     }
  3087.  
  3088.  
  3089.     /**
  3090.      * Remove a VetoableChangeListener from the listener list.
  3091.      * This removes a VetoableChangeListener that was registered
  3092.      * for all properties.
  3093.      * <p>
  3094.      * This method will migrate to java.awt.Component in the next major JDK release
  3095.      *
  3096.      * @param listener  The VetoableChangeListener to be removed
  3097.      */
  3098.     public synchronized void removeVetoableChangeListener(VetoableChangeListener listener) {
  3099.         if (vetoableChangeSupport == null) {
  3100.             return;
  3101.         }
  3102.         vetoableChangeSupport.removeVetoableChangeListener(listener);
  3103.     }
  3104.  
  3105.  
  3106.     /**
  3107.      * Returns the top-level ancestor of this component (either the
  3108.      * containing Window or Applet), or null if this component has not
  3109.      * been added to any container.
  3110.      *
  3111.      * @return the top-level Container which this component is in.
  3112.      */
  3113.     public Container getTopLevelAncestor() {
  3114.         for(Container p = this; p != null; p = p.getParent()) {
  3115.             if(p instanceof Window || p instanceof Applet) {
  3116.                 return p;
  3117.             }
  3118.         }
  3119.         return null;
  3120.     }
  3121.  
  3122.  
  3123.     /**
  3124.      * Registers <i>listener</i> so that it will receive AncestorEvents
  3125.      * when it or any of its ancestors move or are made visible / invisible.
  3126.      * Events are also sent when the component or its ancestors are added
  3127.      * or removed from the Component hierarchy
  3128.      * <p>
  3129.      * This method will migrate to java.awt.Component in the next major JDK release
  3130.      *
  3131.      * @see AncestorEvent
  3132.      */
  3133.     public void addAncestorListener(AncestorListener listener) {
  3134.         if (ancestorNotifier == null) {
  3135.             ancestorNotifier = new AncestorNotifier(this);
  3136.         }
  3137.         ancestorNotifier.addAncestorListener(listener);
  3138.     }
  3139.  
  3140.     /**
  3141.      * Unregisters <i>listener</i> so that it will no longer receive
  3142.      * AncestorEvents
  3143.      * <p>
  3144.      * This method will migrate to java.awt.Component in the next major JDK release
  3145.      *
  3146.      * @see #addAncestorListener
  3147.      */
  3148.     public void removeAncestorListener(AncestorListener listener) {
  3149.         if (ancestorNotifier == null) {
  3150.             return;
  3151.         }
  3152.         ancestorNotifier.removeAncestorListener(listener);
  3153.         if (ancestorNotifier.listenerList.getListenerList().length == 0) {
  3154.             ancestorNotifier.removeAllListeners();
  3155.             ancestorNotifier = null;
  3156.         }
  3157.     }
  3158.  
  3159.  
  3160.     /**
  3161.      * Notification to this component that it now has a parent component.
  3162.      * When this method is invoked, the chain of parent components is
  3163.      * set up with KeyboardAction event listeners.
  3164.      *
  3165.      * @see #registerKeyboardAction
  3166.      */
  3167.     public void addNotify() {
  3168.         super.addNotify();
  3169.         firePropertyChange("ancestor", null, getParent());
  3170.  
  3171.  
  3172.         Hashtable bindings = (Hashtable) getClientProperty(KEYBOARD_BINDINGS_KEY);
  3173.     if( bindings == null)
  3174.         return;
  3175.  
  3176.     Enumeration iter = bindings.keys();
  3177.     while (iter.hasMoreElements()) {
  3178.         KeyStroke ks = (KeyStroke)iter.nextElement();
  3179.         KeyboardBinding aBinding = (KeyboardBinding)bindings.get(ks);
  3180.         if (aBinding.condition == WHEN_IN_FOCUSED_WINDOW) {
  3181.             registerWithKeyboardManager(ks);
  3182.         }
  3183.     }
  3184.     }
  3185.  
  3186.  
  3187.     /**
  3188.      * Notification to this component that it no longer has a parent component.
  3189.      * When this method is invoked, any KeyboardActions set up in the
  3190.      * the chain of parent components are removed.
  3191.      *
  3192.      * @see #registerKeyboardAction
  3193.      */
  3194.     public void removeNotify() {
  3195.         super.removeNotify();
  3196.         // This isn't strictly correct.  The event shouldn't be
  3197.         // fired until *after* the parent is set to null.  But
  3198.         // we only get notified before that happens
  3199.         firePropertyChange("ancestor", getParent(), null);
  3200.  
  3201.         Hashtable bindings = (Hashtable) getClientProperty(KEYBOARD_BINDINGS_KEY);
  3202.     if( bindings == null)
  3203.         return;
  3204.  
  3205.     Enumeration iter = bindings.keys();
  3206.     while (iter.hasMoreElements()) {
  3207.         KeyStroke ks = (KeyStroke)iter.nextElement();
  3208.         KeyboardBinding aBinding = (KeyboardBinding)bindings.get(ks);
  3209.         if (aBinding.condition == WHEN_IN_FOCUSED_WINDOW) {
  3210.             unregisterWithKeyboardManager(ks);
  3211.         }
  3212.     }
  3213.     }
  3214.  
  3215.  
  3216.     /**
  3217.      * Adds the specified region to the dirty region list if the component
  3218.      * is showing.  The component will be repainted after all of the
  3219.      * currently pending events have been dispatched.
  3220.      *
  3221.      * @see java.awt.Component#isShowing
  3222.      * @see RepaintManager#addDirtyRegion
  3223.      */
  3224.     public void repaint(long tm, int x, int y, int width, int height) {
  3225.         RepaintManager.currentManager(this).addDirtyRegion(this, x, y, width, height);
  3226.     }
  3227.  
  3228.  
  3229.     /**
  3230.      * Adds the specified region to the dirty region list if the component
  3231.      * is showing.  The component will be repainted after all of the
  3232.      * currently pending events have been dispatched.
  3233.      *
  3234.      * @see java.awt.Component#isShowing
  3235.      * @see RepaintManager#addDirtyRegion
  3236.      */
  3237.     public void repaint(Rectangle r) {
  3238.         repaint(0,r.x,r.y,r.width,r.height);
  3239.     }
  3240.  
  3241.  
  3242.     /**
  3243.      * Support for deferred automatic layout.  
  3244.      * <p> 
  3245.      * Calls invalidate() and then adds this components validateRoot
  3246.      * to a list of components that need to be validated.  Validation
  3247.      * will occur after all currently pending events have been dispatched.
  3248.      * In other words after this method is called,  the first validateRoot
  3249.      * (if any) found when walking up the containment hierarchy of this 
  3250.      * component will be validated.
  3251.      * By default, JRootPane, JScrollPane, and JTextField return true 
  3252.      * from isValidateRoot().
  3253.      * <p>
  3254.      * This method will automatically be called on this component 
  3255.      * when a property value changes such that size, location, or 
  3256.      * internal layout of this component has been affected.  This automatic
  3257.      * updating differs from the AWT because programs generally no
  3258.      * longer need to invoke validate() to get the contents of the
  3259.      * GUI to update. 
  3260.      * <p>
  3261.      *
  3262.      * @see java.awt.Component#invalidate
  3263.      * @see java.awt.Container#validate
  3264.      * @see #isValidateRoot
  3265.      * @see RepaintManager#addInvalidComponent
  3266.      */
  3267.     public void revalidate() {
  3268.         if (getParent() == null) {
  3269.             invalidate();
  3270.         }
  3271.         else if (SwingUtilities.isEventDispatchThread()) {
  3272.             invalidate();
  3273.             RepaintManager.currentManager(this).addInvalidComponent(this);
  3274.         }
  3275.         else {
  3276.             Runnable callRevalidate = new Runnable() {
  3277.                 public void run() {
  3278.                     revalidate();
  3279.                 }
  3280.             };
  3281.             SwingUtilities.invokeLater(callRevalidate);
  3282.         }
  3283.     }
  3284.  
  3285.     /**
  3286.      * If this method returns true, revalidate() calls by descendants of
  3287.      * this component will cause the entire tree beginning with this root
  3288.      * to be validated.  Returns false by default.  JScrollPane overrides
  3289.      * this method and returns true.
  3290.      *
  3291.      * @return false
  3292.      * @see #revalidate
  3293.      * @see java.awt.Component#invalidate
  3294.      * @see java.awt.Container#validate
  3295.      */
  3296.     public boolean isValidateRoot() {
  3297.         return false;
  3298.     }
  3299.  
  3300.  
  3301.     /**
  3302.      * Returns true if this component tiles its children, i.e. if
  3303.      * it can guarantee that the children will not overlap.  The
  3304.      * repainting system is substantially more efficient in this
  3305.      * common case.  JComponent subclasses that can't make this
  3306.      * guarantee, e.g. JLayeredPane, should override this method
  3307.      * to return false.
  3308.      *
  3309.      * @return true if this components children don't overlap
  3310.      */
  3311.     public boolean isOptimizedDrawingEnabled() {
  3312.         return true;
  3313.     }
  3314.  
  3315.  
  3316.     /**
  3317.      * Paint the specified region in this component and all of its
  3318.      * descendants that overlap the region, immediately.
  3319.      * <p>
  3320.      * It's rarely neccessary to call this method.  In most cases it's
  3321.      * more efficient to call repaint which defers the actual painting
  3322.      * and can collapse redundant requests into a single paint call.
  3323.      * This method is useful if one needs to update the display while
  3324.      * the current event is being dispatched.
  3325.      *
  3326.      * @see #repaint
  3327.      */
  3328.     public void paintImmediately(int x,int y,int w, int h) {
  3329.         Component c = this;
  3330.         Component parent;
  3331.         Rectangle bounds;
  3332.  
  3333.         if(!isShowing()) {
  3334.             return;
  3335.         }
  3336.         while(!((JComponent)c).isOpaque()) {
  3337.             parent = c.getParent();
  3338.             if(parent != null) {
  3339.                 if(c instanceof JComponent) {
  3340.                     bounds = ((JComponent)c)._bounds;
  3341.                 } else {
  3342.                     bounds = c.getBounds();
  3343.                 }
  3344.                 x += bounds.x;
  3345.                 y += bounds.y;
  3346.                 c = parent;
  3347.             } else {
  3348.                 break;
  3349.             }
  3350.  
  3351.             if(!(c instanceof JComponent)) {
  3352.                 break;
  3353.             }
  3354.         }
  3355.         if(c instanceof JComponent) {
  3356.             ((JComponent)c)._paintImmediately(x,y,w,h);
  3357.         } else {
  3358.             c.repaint(x,y,w,h);
  3359.         }
  3360.     }
  3361.  
  3362.     /**
  3363.      * Paint the specified region now.
  3364.      * <p>
  3365.      * This method will migrate to java.awt.Component in the next major JDK release
  3366.      */
  3367.     public void paintImmediately(Rectangle r) {
  3368.         paintImmediately(r.x,r.y,r.width,r.height);
  3369.     }
  3370.  
  3371.     /**
  3372.      * Return whether this component should be guaranteed to be on top.
  3373.      * For examples, it would make no sense for Menus to pop up under
  3374.      * another component, so they would always return true. Most components
  3375.      * will want to return false, hence that is the default.
  3376.      */
  3377.     // package private
  3378.     boolean alwaysOnTop() {
  3379.     return false;
  3380.     }
  3381.  
  3382.     private Rectangle paintImmediatelyClip = new Rectangle(0,0,0,0);
  3383.  
  3384.     void _paintImmediately(int x, int y, int w, int h) {
  3385.         Graphics g;
  3386.         Container c;
  3387.         Rectangle b;
  3388.  
  3389.     int tmpX, tmpY, tmpWidth, tmpHeight;
  3390.         int offsetX=0,offsetY=0;
  3391.  
  3392.         boolean hasBuffer = false;
  3393.  
  3394.         JComponent bufferedComponent = null;
  3395.         JComponent paintingComponent = this;
  3396.  
  3397.         RepaintManager repaintManager = RepaintManager.currentManager(this);
  3398.  
  3399.     tmpX = tmpY = tmpWidth = tmpHeight = 0;
  3400.  
  3401.         paintImmediatelyClip.x = x;
  3402.         paintImmediatelyClip.y = y;
  3403.         paintImmediatelyClip.width = w;
  3404.         paintImmediatelyClip.height = h;
  3405.  
  3406.     
  3407.     // System.out.println("1) ************* in _paintImmediately for " + this);
  3408.     
  3409.     boolean ontop = alwaysOnTop() && isOpaque();
  3410.  
  3411.     for (c = this; c != null && !(c instanceof Window) && !(c instanceof Applet); c = c.getParent()) {
  3412.         if(!ontop && (c instanceof JComponent) &&
  3413.                    !(((JComponent)c).isOptimizedDrawingEnabled())) {
  3414.             paintingComponent = (JComponent)c;
  3415.             offsetX = offsetY = 0;
  3416.             hasBuffer = false; /** Get rid of any buffer since we draw from here and
  3417.                     *  we might draw something larger
  3418.                     */
  3419.         }
  3420.         
  3421.         // look to see if the parent (and therefor this component)
  3422.         // is double buffered
  3423.         if(repaintManager.isDoubleBufferingEnabled() &&
  3424.            (c instanceof JComponent) && ((JComponent)c).isDoubleBuffered()) {
  3425.             hasBuffer = true;
  3426.             bufferedComponent = (JComponent) c;
  3427.         }
  3428.  
  3429.         // if we aren't on top, include the parent's clip 
  3430.         if(!ontop) {
  3431.             if(c instanceof JComponent) {
  3432.             b = ((JComponent)c)._bounds;
  3433.             } else {
  3434.             b = c.getBounds();
  3435.             }
  3436.             tmpWidth = b.width;
  3437.             tmpHeight = b.height;
  3438.             SwingUtilities.computeIntersection(tmpX,tmpY,tmpWidth,tmpHeight,paintImmediatelyClip);
  3439.             paintImmediatelyClip.x += b.x;
  3440.             paintImmediatelyClip.y += b.y;
  3441.             offsetX += b.x;
  3442.             offsetY += b.y;
  3443.         }
  3444.     }
  3445.     
  3446.         if(c == null || c.getPeer() == null) {
  3447.             return;
  3448.         }
  3449.  
  3450.     // If the clip width or height is negative, don't bother painting
  3451.     if(paintImmediatelyClip.width <= 0 || paintImmediatelyClip.height <= 0) {
  3452.         return;
  3453.     }
  3454.     
  3455.         paintImmediatelyClip.x -= offsetX;
  3456.         paintImmediatelyClip.y -= offsetY;
  3457.     
  3458.         try {
  3459.             g = SwingGraphics.createSwingGraphics(paintingComponent.getGraphics());
  3460.         } catch(NullPointerException e) {
  3461.             g = null;
  3462.             e.printStackTrace();
  3463.         }
  3464.  
  3465.         if(g == null) {
  3466.             System.err.println("In paintImmediately null graphics");
  3467.             return;
  3468.         }
  3469.  
  3470.         if(hasBuffer) {
  3471.             Image offscreen = repaintManager.getOffscreenBuffer(bufferedComponent,paintImmediatelyClip.width,paintImmediatelyClip.height);
  3472.             paintWithBuffer(paintingComponent,g,paintImmediatelyClip,offscreen);
  3473.             g.dispose();
  3474.         } else {
  3475.         //System.out.println("has no buffer");
  3476.             g.setClip(paintImmediatelyClip.x,paintImmediatelyClip.y,paintImmediatelyClip.width,paintImmediatelyClip.height);
  3477.             try {
  3478.                 paintingComponent.paint(g);
  3479.             } finally {
  3480.                 g.dispose();
  3481.             }
  3482.         }
  3483.     }
  3484.  
  3485.     private void paintWithBuffer(JComponent paintingComponent,Graphics g,Rectangle clip,Image offscreen) {
  3486.         Graphics og = SwingGraphics.createSwingGraphics(offscreen.getGraphics());
  3487.         int bw = offscreen.getWidth(null);
  3488.         int bh = offscreen.getHeight(null);
  3489.         int x,y,maxx,maxy;
  3490.  
  3491.         if(bw > clip.width) {
  3492.             bw = clip.width;
  3493.         }
  3494.         if(bh > clip.height) {
  3495.             bh = clip.height;
  3496.         }
  3497.  
  3498.         try {
  3499.             paintingComponent.setFlag(ANCESTOR_USING_BUFFER,true);
  3500.             paintingComponent.setFlag(IS_PAINTING_TILE,true);
  3501.             for(x = clip.x, maxx = clip.x+clip.width;
  3502.                 x < maxx ;  x += bw ) {
  3503.                 for(y=clip.y, maxy = clip.y + clip.height;
  3504.                     y < maxy ; y += bh) {
  3505.                     if((y+bh) >= maxy && (x+bw) >= maxx) {
  3506.                         paintingComponent.setFlag(IS_PAINTING_TILE,false);
  3507.                     }
  3508.                     og.translate(-x,-y);
  3509.                     og.setClip(x,y,bw,bh);
  3510.                     paintingComponent.paint(og);
  3511.                     g.setClip(x,y,bw,bh);
  3512.                     g.drawImage(offscreen,x,y,paintingComponent);
  3513.                     og.translate(x,y);
  3514.                 }
  3515.             }
  3516.         } finally {
  3517.             paintingComponent.setFlag(ANCESTOR_USING_BUFFER,false);
  3518.             paintingComponent.setFlag(IS_PAINTING_TILE,false);
  3519.             og.dispose();
  3520.         }
  3521.     }
  3522.  
  3523.  
  3524.     private void setFlag(int aFlag, boolean aValue) {
  3525.         if(aValue) {
  3526.             flags |= (1 << aFlag);
  3527.         } else {
  3528.             flags &= ~(1 << aFlag);
  3529.         }
  3530.     }
  3531.  
  3532.     private boolean getFlag(int aFlag) {
  3533.         int mask = (1 << aFlag);
  3534.         return ((flags & mask) == mask);
  3535.     }
  3536.  
  3537.  
  3538.     /** Buffering **/
  3539.  
  3540.     /** Set whether the receiving component should use a buffer to paint.
  3541.      *  If set to true, all the drawing from this component will be done
  3542.      *  in an offscreen painting buffer. The offscreen painting buffer will
  3543.      *  the be copied onto the screen.
  3544.      *  Swing's painting system always use a maximum of one double buffer.
  3545.      *  If a Component is buffered and one of its ancestor is also buffered,
  3546.      *  the ancestor buffer will be used.
  3547.      */
  3548.     public void setDoubleBuffered(boolean aFlag) {
  3549.         setFlag(IS_DOUBLE_BUFFERED,aFlag);
  3550.     }
  3551.  
  3552.     /** Return whether the receiving component should use a buffer to paint. **/
  3553.     public boolean isDoubleBuffered() {
  3554.         return getFlag(IS_DOUBLE_BUFFERED);
  3555.     }
  3556.  
  3557.     /**
  3558.      * Returns the JRootPane ancestor for a component
  3559.      *
  3560.      * @return the JRootPane that contains this component,
  3561.      *         or null if no JRootPane is found
  3562.      */
  3563.     public JRootPane getRootPane() {
  3564.         return SwingUtilities.getRootPane(this);
  3565.     }
  3566.  
  3567.  
  3568.     /** Serialization **/
  3569.  
  3570.     /**
  3571.      * This class is used to give us an oppportunity to uninstall the UI
  3572.      * before java.awt.Container.writeObject() runs.  The enableSerialization()
  3573.      * method belows adds an instance of this class to the FocusListener
  3574.      * field in java.awt.Component.  The java.awt.Component.writeObject()
  3575.      * method, which always runs before java.awt.Container.writeObject(),
  3576.      * effectively calls our writeObject method which takes care of uninstalling
  3577.      * the UI.
  3578.      * <p>
  3579.      * A FocusListener is used (any listener would do) because all Swing 
  3580.      * components listen for Focus events anyway.
  3581.      * <p>
  3582.      * Yes this is a hack.  Unfortunately we don't know of a better way to make 
  3583.      * the UI property transient and work correctly on JDK1.1 VMs.
  3584.      */
  3585.     private class EnableSerializationFocusListener implements FocusListener, Serializable 
  3586.     {
  3587.     public void focusGained(FocusEvent e) {}
  3588.     public void focusLost(FocusEvent e) {}
  3589.     private void writeObject(ObjectOutputStream s) throws IOException {
  3590.         s.defaultWriteObject();
  3591.         if (ui != null) {
  3592.         ui.uninstallUI(JComponent.this);
  3593.         }
  3594.     }
  3595.     }
  3596.  
  3597.  
  3598.     /**
  3599.      * Called by the JComponent constructor.  Adds a fake FocusListener
  3600.      * whose real purpose is to uninstall the components UI early.
  3601.      */
  3602.     void enableSerialization() {
  3603.     addFocusListener(new EnableSerializationFocusListener());
  3604.     }
  3605.  
  3606.  
  3607.     /**
  3608.      * This object is the ObjectInputStream callback that's called after
  3609.      * a complete graph of objects (including at least one JComponent)
  3610.      * has been read.  It sets the UI property of each Swing component 
  3611.      * that was read to the current default with updateUI().  
  3612.      * <p> 
  3613.      * As each  component is read in we keep track of the current set of 
  3614.      * root components here, in the roots vector.  Note that there's only one 
  3615.      * ReadObjectCallback per ObjectInputStream, they're stored in
  3616.      * the static readObjectCallbacks hashtable.
  3617.      * 
  3618.      * @see java.io.ObjectInputStream#registerValidation
  3619.      * @see SwingUtilities#updateComponentTreeUI
  3620.      */
  3621.     private class ReadObjectCallback implements ObjectInputValidation 
  3622.     {
  3623.     private final Vector roots = new Vector(1);
  3624.     private final ObjectInputStream inputStream;
  3625.  
  3626.     ReadObjectCallback(ObjectInputStream s) throws Exception {
  3627.         inputStream = s;
  3628.         s.registerValidation(this, 0);
  3629.     }
  3630.  
  3631.     /**
  3632.      * This is the method that's called after the entire graph
  3633.      * of objects has been read in.  It initializes
  3634.      * the UI property of all of the copmonents with
  3635.      * SwingUtilities.updateComponentTreeUI().
  3636.      */
  3637.     public void validateObject() throws InvalidObjectException {
  3638.         try {
  3639.         for(int i = 0; i < roots.size(); i++) {
  3640.             JComponent root = (JComponent)(roots.elementAt(i));
  3641.             SwingUtilities.updateComponentTreeUI(root);
  3642.         }
  3643.         }
  3644.         finally {
  3645.         readObjectCallbacks.remove(inputStream);
  3646.         }
  3647.     }
  3648.  
  3649.     /**
  3650.      * If c isn't a descendant of a component we've already
  3651.      * seen, then add it to the roots Vector.
  3652.      */
  3653.     private void registerComponent(JComponent c)
  3654.         {
  3655.             /* If the Component c is a descendant of one of the
  3656.          * existing roots (or it IS an existing root), we're done.
  3657.          */
  3658.         for(int i = 0; i < roots.size(); i++) {
  3659.         JComponent root = (JComponent)roots.elementAt(i);
  3660.         for(Component p = c; p != null; p = p.getParent()) {
  3661.             if (p == root) {
  3662.             return;
  3663.             }
  3664.         }
  3665.         }
  3666.         
  3667.         /* Otherwise: if Component c is an ancestor of any of the 
  3668.          * existing roots then remove them and add c (the "new root") 
  3669.          * to the roots vector.
  3670.          */
  3671.         for(int i = 0; i < roots.size(); i++) {
  3672.         JComponent root = (JComponent)roots.elementAt(i);
  3673.         for(Component p = root.getParent(); p != null; p = p.getParent()) {
  3674.             if (p == c) {
  3675.             roots.removeElementAt(i--); // !!
  3676.             break;
  3677.             }
  3678.             p = p.getParent();
  3679.         }
  3680.         }
  3681.         
  3682.         roots.addElement(c);
  3683.     }
  3684.     }
  3685.  
  3686.  
  3687.     /**
  3688.      * We use the ObjectInputStream "registerValidation" callback to 
  3689.      * update the UI for the entire tree of components after they've
  3690.      * all been read in.
  3691.      * 
  3692.      * @see ReadObjectCallback
  3693.      */
  3694.     private void readObject(ObjectInputStream s) 
  3695.     throws IOException, ClassNotFoundException 
  3696.     {
  3697.         s.defaultReadObject();
  3698.  
  3699.     /* If there's no ReadObjectCallback for this stream yet, i.e. if
  3700.      * this is the first call to JComponent.readObject() for this
  3701.      * graph of objects, then create a callback and stash it
  3702.      * in the readObjectCallbacks table.  Note that the ReadObjectCallback
  3703.      * constructor takes care of calling s.registerValidation().
  3704.      */
  3705.     ReadObjectCallback cb = (ReadObjectCallback)(readObjectCallbacks.get(s));
  3706.     if (cb == null) {
  3707.         try {
  3708.         readObjectCallbacks.put(s, cb = new ReadObjectCallback(s));
  3709.         }
  3710.         catch (Exception e) {
  3711.         throw new IOException(e.toString());
  3712.         }
  3713.     }
  3714.     cb.registerComponent(this);
  3715.     }
  3716.  
  3717.  
  3718.     /**
  3719.      * Before writing a JComponent to an ObjectOutputStream we temporarily 
  3720.      * uninstall its UI.  This is tricky to do because we want to uninstall
  3721.      * the UI before any of the JComponents children (or its LayoutManager etc.)
  3722.      * are written, and we don't want to restore the UI until the most derived
  3723.      * JComponent subclass has been been stored.  
  3724.      */
  3725.     private void writeObject(ObjectOutputStream s) throws IOException {
  3726.         s.defaultWriteObject();
  3727.     if ((ui != null) && (getUIClassID().equals(uiClassID))) {
  3728.         ui.installUI(this);
  3729.     }
  3730.     }
  3731.  
  3732.  
  3733.     /**
  3734.      * Returns a string representation of this JComponent. This method 
  3735.      * is intended to be used only for debugging purposes, and the 
  3736.      * content and format of the returned string may vary between      
  3737.      * implementations. The returned string may be empty but may not 
  3738.      * be <code>null</code>.
  3739.      * <P>
  3740.      * Overriding paramString() to provide information about the
  3741.      * specific new aspects of the JFC components.
  3742.      * 
  3743.      * @return  a string representation of this JComponent.
  3744.      */
  3745.     protected String paramString() {
  3746.         String preferredSizeString = (preferredSize != null ?
  3747.                       preferredSize.toString() : "");
  3748.         String minimumSizeString = (minimumSize != null ?
  3749.                     minimumSize.toString() : "");
  3750.         String maximumSizeString = (maximumSize != null ?
  3751.                     maximumSize.toString() : "");
  3752.         String borderString = (border != null ?
  3753.                    border.toString() : "");
  3754.  
  3755.         return super.paramString() +
  3756.         ",alignmentX=" + alignmentX +
  3757.         ",alignmentY=" + alignmentY +
  3758.         ",border=" + borderString +
  3759.     ",flags=" + flags +             // should beef this up a bit
  3760.         ",maximumSize=" + maximumSizeString +
  3761.         ",minimumSize=" + minimumSizeString +
  3762.         ",preferredSize=" + preferredSizeString;
  3763.     }
  3764.  
  3765. }
  3766.  
  3767.  
  3768.  
  3769.